输入文本 - "默认值"未加载状态值,并且"值"未在更改时更新



我有一个输入文本如下(MovieInput.tsx(:

<input 
id="inputMovieTitle" 
type="text"
onChange={ e => titleHandleChange(e) }
value={ getTitle() }>
</input>

titleHandleChange:

const [title, setTitle] = useState('');
const titleHandleChange = (e: ChangeEvent<HTMLInputElement>) => {        
setTitle(e.target.value);
}

getTitle:

const moviesInState = useSelector((state: any) => state.movies);
const getTitle = () => {      
console.log(moviesInState.item.title); // It displays correct movie title from the store corresponding to the selected row
return moviesInState.item.title;
}

我有一个表(Grid.tsx(,它列出了状态(state.movies.items[](中的所有电影。当我单击该表中的任何电影行时,所选电影将在商店中更新,即state.moviies.item.

网格.tsx:

const dispatch = useDispatch();
const selectMovie = (movie: Movie) => {
const movieSelected: Movie = {
_id: movie._id,
__v: movie.__v,
title: movie.title,
rating: movie.rating,
year: movie.year
}
dispatch(getMovie(movieSelected));
}
...
<tbody>
{
props.allMovies.map((movie: Movie) => 
<tr onClick={() => selectMovie(movie)}>
<td>{movie.title}</td>
<td>{(+movie.rating).toFixed(1)}</td>
<td>{movie.year}</td>
</tr>
)
}
</tbody>

现在,当我单击表中的任何一行(Grid.tsx(时,它会更新存储中的store.movies.item,并且文本输入(MovieInput.tsx中(显示所选电影的标题。当我更改所选行时,文本输入的值也会更新。

为什么要在文本输入中加载所选电影的标题文本

因为,我应该能够编辑标题值并更新DB中的记录。我选择任何一行,更改其标题,然后单击"更新"按钮并保存。然而,尽管文本已成功填充到文本输入中,并且在更改所选行时进行了正确更改,但文本输入仍然"不可编辑"。这是由于以下代码造成的:

value={ getTitle() }>

当我按如下方式将"value"更改为"defaultValue"时,我可以编辑文本输入,但这一次,当我选择另一行时,文本值不会更改。

defaultValue={ getTitle() }>

它工作得很好,并显示更新的值(当我更改选定的行时(,直到我编辑输入。第一次编辑后,在另一次单击行时不会更改其值。只保留编辑后的文本,但我希望在选择另一行时该值会发生更改。但是,getTitle((函数内的控制台日志会显示与所选行相对应的存储(store.movies.item(中的正确标题。

你能告诉我如何做以下事情吗?

  • 使文本输入可编辑
  • 使文本输入在更改所选行后更改其值(即使在输入丢失编辑并更改为新值之前对其进行了编辑(

输入在更改后不显示更新值的原因是因为它通过moviesInState绑定到redux存储中的值。

据我所见,您希望输入的初始值来自getTitle(),而输入的更新值应该来自用户键入的任何内容。

因此,您应该更改的第一件事是使用存储中的值设置title状态的初始值。

const moviesInState = useSelector((state: any) => state.movies);
const getTitle = () => {      
console.log(moviesInState.item.title); // It displays correct movie title from the store corresponding to the selected row
return moviesInState.item.title;
}
const [title, setTitle] = useState(getTitle());

假设输入必须随着存储的更新而更新,则需要useEffect钩子来传播状态中的更新。

useEffect(() => {
if (moviesInState.item.title !== title) {
setTitle(moviesInState.item.title);
}
}, [moviesInState]);

接下来,将title状态绑定到inputvalue道具。titleHandleChange方法没有问题,所以我们可以保持原样。此外,不需要依赖defaultValue,因此我们可以取消对它的使用。

<input 
id="inputMovieTitle" 
type="text"
onChange={titleHandleChange}
value={title}>
</input>

另一方面,您不应该使用any,因为这将删除TypeScript的类型检查功能的好处。相反,您应该将state参数定义为您为redux存储定义的根状态类型。例如,

const moviesInState = useSelector((state: RootState) => state.movies);

相关内容

最新更新