好的,我已经知道一种方法。但是,我是在问这个问题,以防我重新发明轮子,因为我是React的新手。我的印象是,如果父组件通过道具将其状态传递给子组件,而不是更新父组件的状态,则子组件将在需要时重新渲染。但这似乎并非如此。我设置了这个示例,
class Child extends Component {
constructor(props) {
super(props);
this.state = {
number: props.number,
};
}
updateNumber(n) {
this.setState({number: n});
}
render() {
return (<h1>{this.state.number}</h1>);
}
}
class Parent extends Component {
constructor(props) {
super(props);
this.state = {
number: -1,
};
this.child = React.createRef();
setInterval(this.updateState.bind(this), 1000);
}
updateState() {
console.log(this.state);
this.setState({
number: Math.floor((Math.random() * 10) + 1),
});
// this.child.current.updateNumber(this.state.number);
}
render() {
return (
<div>
<Child ref={this.child} number={this.state.number}/>
</div>
);
}
}
在此示例中,除非我明确定义引用并使用它来调用子级的update函数(注释部分),否则不会在每次更新父级状态时重新渲染子级。就是这样吗?如果您要手动更新孩子的状态(heh),或者如果他们的父母的状态作为道具传递给孩子,他们是否应该自动更新(并因此重新渲染)。
答案 0 :(得分:2)
这是因为您的Child组件也正在使用其自己的状态。总是问自己state
是否必要,这是React初学者的常见错误。
希望您可以通过查看此示例来进一步了解它。建议您不要在构造函数中调用setInterval
,而建议在componentDidMount
中调用它,而在componentWillUnmount
中调用clearInterval
。
// Since you are not using state, you can use functional component for your Child component
const Child = ({ number }) => <h1>{number}</h1>;
class Parent extends React.Component {
constructor(props) {
super(props);
this.timer = null;
this.state = { number: 0 };
}
componentDidMount() {
// setInterval after component did mount
this.timer = setInterval(this.incrementNumber, 1000);
}
componentWillUnmount() {
// clearInterval when component is going to unmount
if (this.timer) {
clearInterval(this.timer);
}
}
incrementNumber = () => {
// setState function callback to ensure state received will be latest state
this.setState(prevState => ({ number: prevState.number + 1 }));
}
render() {
const { number } = this.state;
return (
<div>
<Child number={number} />
</div>
);
}
}
答案 1 :(得分:1)
您的方法是错误的,不要像这样从子级更新您的父级状态,也不要将道具在子级中保存,因为它们已随着父级更新而更新。
如果您想更新父级表单子级,则将道具表单子级传递给父级。当父级更新子级也将更新时。
class Child extends Component {
constructor(props) {
super(props);
}
updateNumber=()=>{// update parent form child. call this function in somewhere in your component. if you want to pass event pass it as second argument
this.props.updateNumber(newUpdatedNumber,event);
}
render() {
return (<h1>{this.props.number}</h1>);
}
}
class Parent extends Component {
constructor(props) {
super(props);
this.state = {
number: -1,
};
this.child = React.createRef();
setInterval(this.updateState.bind(this), 1000);
}
updateState() {
console.log(this.state);
this.setState({
number: Math.floor((Math.random() * 10) + 1),
});
}
//update parent from child
updateParentFromChild=(updatedNumber,event)=>{//catch function from child
this.setState({
number:updatedNumber
});
}
render() {
return (
<div>
<Child ref={this.child} updateNumber={this.updateParentFromChild} number={this.state.number}/>
</div>
);
}
}
答案 2 :(得分:0)
重新渲染孩子的一个简单选择是每次需要重新渲染时都更新唯一的键属性。
C:\Program Files\dotnet\sdk\3.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.PackageDependencyResolution.targets(234,
5): error NETSDK1064: Package Microsoft.CodeAnalysis.Analyzers, version 2.9.3 was not found. It might have
been deleted since NuGet restore. Otherwise, NuGet restore might have only partially completed, which
might have been due to maximum path length restrictions. [C:\Program Files
(x86)\Jenkins\workspace\test\ProductCoreApi\ProductCoreApi.csproj]