【发布时间】:2020-04-07 03:28:03
【问题描述】:
我在 React 中有一个组件,它呈现 @material-ui 表(如果重要,可以通过 React 路由器访问)。在表格内,我有一个 react-select 下拉菜单,但它是通过单独的组件呈现的。这是该父组件的代码:
return(
<>
<Table aria-label="customized table">
<TableHead>
<TableRow>
<StyledTableCell align="center"><GameTypeSelector onGameTypeChange={setSelectedGameType} gameTypes={gameTypes} /></StyledTableCell>
...
显然,我将在第二次访问的GameTypeSelector 呈现下拉菜单,gameTypes 包含它的选项。 setSelectedGameType 应该更新一个本地状态变量,每次下拉列表更改时都会保存新值:
const [selectedGameType, setSelectedGameType] = useState(null);
所以最后一件事是其他组件本身。这也很简单:
const [selected, setSelected] = useState({ value: "", label: "Please select game type" });
const [options, setOptions] = useState([]);
useEffect(() => {
//set options here
}, [props]);
useEffect(() => {
console.log("in use effect of gamte type selectedo");
props.onGameTypeChange(selected.value);
}, [selected.value, props]);
return (
<>
<Select
value={selected}
onChange={selectedOption => setSelected({ value: selectedOption.value, label: selectedOption.label })}
options={[{ value: null, label: "All" }, ...options]}
/>
</>
);
当我从下拉列表中更改值时,会发生最奇怪的事情。它更新本地selected,然后从父控制器调用该函数。该功能轮流更新selectedGameType,它仍然可以正常工作。
但是,在更新之后,它会再次重新渲染表中的GameTypeSelector,然后将内部的selected 值设置为来自useState({ value: "", label: "Please select game type" }); 这一行的默认值。之后,selectedGameType 的父值也设置为空。
在浏览器中它看起来像这样:我从下拉列表中选择一个值,将其设置在其中,更新父组件(通过不同的控制台日志计算出那么多),然后重置 GameTypeSelector 组件并运行为其默认值。它只重新渲染该单个部分,表格的其余部分保持不变并且不会重新渲染,并且代码中没有任何内容触及其他任何地方的selectedGameType。
知道有什么问题吗?我想我在这里遗漏了一些重要的东西,但我不知道是什么?
【问题讨论】:
-
如果您可以设置一个代码n-p 或沙箱,它会更容易理解。从表面上看,您似乎有两个单独的状态挂钩来跟踪相同的数据块,即选择的游戏类型,对吗?其中一个在父母中,其中一个在孩子中……我会说孩子正在重新渲染,因为父母的状态被孩子改变了。一个 hacky 解决方案可能是向您的 GameTypeSelector 添加另一个道具,该道具将传递当前选择的内容,然后将该道具用作 useState 默认值。
-
在父组件中:
<GameTypeSelector onGameTypeChange={setSelectedGameType} gameTypes={gameTypes} selectedGameType={selectedGameType} />在子组件中:const [selected, setSelected] = useState(props.selectedGameType || { value: "", label: "Please select game type" }) -
好的,我可以看到问题出在哪里,但您的建议不起作用 - 它的行为与我描述的相同。我需要父组件中下拉列表中的值来执行 API 调用,所以我需要在那里引用它...有什么更聪明的方法来解决整个问题吗?
标签: reactjs react-hooks react-functional-component