为什么父组件总是显示比子组件少1? 第一次更新后不会重新渲染。
export const Parent = (props) => {
const [count, setCount] = React.useState(0);
return (
<View>
<Text>Parent: {count}</Text>
<Child updateCount={setCount} />
</View>
);
};
const Child = (props) => {
const [count, setCount] = React.useState(0);
const updateCount = () => {
setCount((count) => count + 1);
return props.updateCount(count);
};
return (
<View>
<Text>Child: {count}</Text>
<Button title="add" onPress={updateCount} />
</View>
);
};
答案 0 :(得分:2)
主要问题是您希望 setCount
立即发生,尽管它是一个异步操作。问题出在以下代码中的 <Child />
组件中:
const updateCount = () => {
setCount((count) => count + 1)
return props.updateCount(count)
}
从技术上讲,您希望 count
被更新并传递给 props.updatedCount
,同时它仍然具有以前的值。
这也与问题无关,但您实际上并不需要从更新状态的函数返回,因此只需删除 return
关键字。
解决这个问题有多种选择。
只需以与另一个 props.updateCount
完全相同的方式调用 setState
为:
const updateCount = () => {
setCount((count) => count + 1)
props.updateCount((count) => count + 1)
}
<Parent />
中保持一种状态并通过 props 向下传递:所以主要的解决方案是:
export const Parent = (props) => {
const [count, setCount] = React.useState(0);
return (
<View>
<Text>Parent: {count}</Text>
{/* passed here count as well: */}
<Child updateCount={setCount} count={count} />
</View>
);
};
// destructure here updateCount and count
const Child = ({ updateCount, count }) => {
return (
<View>
{/* using here count from parent */}
<Text>Child: {count}</Text>
{/* calling here updateCount from the props as: */}
<Button title="add" onPress={() => updateCount((count) => count + 1} />
</View>
);
};
Context
API:通过使用 Context
,您可以执行以下操作,参见文档:
Context 提供了一种通过组件树传递数据的方法,而无需在每个级别手动向下传递 props。
通常,一旦我们拥有比当前更复杂的组件树,我就喜欢使用 Context
。所以我建议保留一种状态选项。
答案 1 :(得分:1)
@norbital 的 N°2 解决方案很有魅力,就我而言,它是类组件而不是功能组件。在这里只发布一个适合类组件的答案 所以这个想法是在父组件中保持状态并与子组件共享它作为道具。然后在子组件中对其进行任何我们想要的操作。
export default class CraGenerator extends React.Component {
constructor(props) {
super(props);
this.state = {
number: 0
}
getNumberFromChild(data) {
this.setState({ number: data });
}
render() {
return (
<div onClick={this.increment.bind(this)}>
<Child getNumberFromChild={this.getNumberFromChild.bind(this)} number={this.state.number}/>
</div>
)
}
export default class Child extends React.Component {
constructor(props) {
super(props)
this.state = {
number: this.props.number
}
}
increment() {
this.setState({ number: this.state.number + 1 });
this.props.getNumberFromChild(this.state.number + 1);
}
render() {
return (
<div onClick={this.increment.bind(this)}>
Click me...increment me ::: {this.state.number}
</div>
);
}
}
答案 2 :(得分:0)
将代码的逻辑部分移到父级,而将子级保留为按钮和文本。这样做:
export const Parent = (props) => {
const [count, setCount] = React.useState(0);
const handleCount = () => {
setCount = count + 1
}
return (
<View>
<Text>Parent: {count}</Text>
<Child updateCount={setCount} count={count}/>
</View>
);
};
const Child = (props) => {
return (
<View>
<Text>Child: {props.count}</Text>
<Button title="add" onPress={()=>props.updateCount()} />
</View>
);
};
答案 3 :(得分:0)
我做了一个例子here:
const updateCount = () => {
setCount((count) => count + 1); // <=== you did it here correctly
return props.updateCount(count); // the problem is here
};
发生这种情况是因为它没有收到最新的 count 值,这是在下一次重新渲染时发生的,所以它总是落后一步。要解决此问题,只需执行相同的操作,此处的 return
是多余的。
const updateCount = () => {
setCount((count) => count + 1);
props.updateCount((count) => count + 1); // problem fixed
};