【发布时间】:2021-08-15 10:21:07
【问题描述】:
我正在尝试将键值对的对象传递给父组件,该对象的值是字符串数组。这些值将来自 UI-Kitten 的多选组件,并将作为对象传递给 Parent。
我了解数据在父组件和子组件之间的传递方式以及 useEffect 在组件中用于 componentDidMount 或效果的任何条件触发的用法。但是这个案例比较复杂。
我可能会将整个子组件转储到父组件中,因为我尝试复制类似的东西并且它有效,即每当用户从多选中选择/取消选择一个选项时,我都会更新键值对的对象。希望我可以使用 Child-Parent,这样 Parent 就不会因为 Child 组件很长而混乱。
我希望我能得到一些帮助。谢谢!
父组件(状态,techniqueExperience,未更新):
const [technologyExperience, setTechnologyExperience] = React.useState({
game: [],
web: [],
mobile: [],
database: [],
machineLearning: []
});
const getSelections = data => {
setTechnologyExperience(prevData => {
return { ...prevData, ...data };
});
// Only prints on first load
console.log('parent.getSelections', technologyExperience);
};
React.useEffect(() => {
// Only prints on first load
console.log('parent.useEffect.getSelections', technologyExperience);
}, [getSelections]);
// calling of the Child component
<InputBackgroundSelect getSelections={getSelections} />
子组件:
const InputBackgroundSelect = props => {
// All the values needed to pass to Parent
const [gameIndex, setGameIndex] = React.useState([]);
const displayGameDev = gameIndex.map(index => {
return gameDevData[index.row];
});
const [webIndex, setWebIndex] = React.useState([]);
const displayWebDev = webIndex.map(index => {
return webDevData[index.row];
});
const [mobileIndex, setMobileIndex] = React.useState([]);
const displaymobileDev = mobileIndex.map(index => {
return mobileDevData[index.row];
});
const [dbIndex, setDBIndex] = React.useState([]);
const displayDb = dbIndex.map(index => {
return dbData[index.row];
});
const [mlIndex, setMLIndex] = React.useState([]);
const displayMl = mlIndex.map(index => {
return mlData[index.row];
});
// As for the conditional effect, I have tried using
// [displayGameDev, displayWebDev, displaymobileDev, displayDb, displayMl] too.
React.useEffect(() => {
// Only prints on first load but not when selecting/deselecting options
console.log('Calling props.getSelections');
props.getSelections({
game: displayGameDev,
web: displayWebDev,
mobile: displaymobileDev,
database: displayDb,
machineLearning: displayMl
});
}, [setGameIndex, setWebIndex, setMobileIndex, setDBIndex, setMLIndex]);
// An example of the 5 repeated Selects
<Select
label='Mobile Development'
style={styles.selectInput}
multiSelect={true}
selectedIndex={mobileIndex}
onSelect={index => setMobileIndex(index)} // Fires when user selects an option from the Select
placeholder='Select'
value={displaymobileDev.join(', ')}
>
{mobileDevData.map((value, key) => (
<SelectItem key={key} title={value} />
))}
</Select>
【问题讨论】:
-
当
useEffect在父级中触发时,您是否至少看到更新的technologyExperience?顺便说一句,您对该效果的依赖有误,它应该是technologyExperience。 -
@DrewReese :如果使用此问题中的代码,则不会打印。仅在首次加载时打印。我已将依赖项更改为
technologyExperience,也无济于事。 -
您是否验证了父级中的
getSelections正在被调用?如果您在状态更新之前将控制台日志放在那里,您会看到日志吗?您是否看到 入队状态更新后的日志? -
显然,
getSelections只在屏幕显示时调用一次,其他 2 个useEffect声明也是如此。我已经更新了上面的代码以获得更好的说明。验证父级中的getSelections仅在屏幕显示时调用一次。在状态更新之前,是的,我看到了日志parent.getSelections ...和parent.useEffect.getSelections ...不,我在排队状态更新后看不到日志 -
修复子组件中的
useEffect依赖,这样效果才能真正正确运行。您似乎对 React 钩子依赖项是什么有误解。除了mobileIndex,您实际上是否更新了子其他中的任何状态?
标签: javascript reactjs react-native react-hooks use-effect