[英]Trigger child re-rendering in React.js
父( MyList
在我的例子)组件呈现直通一个孩子(阵列MyComponent
)组件。 父级决定更改数组中的属性,React 触发子级重新渲染的方式是什么?
我想出的只是this.setState({});
调整数据后在 Parent 中。 这是 hack 还是 React 触发更新的方式?
JS小提琴: https : //jsfiddle.net/69z2wepo/7601/
var items = [
{id: 1, highlighted: false, text: "item1"},
{id: 2, highlighted: true, text: "item2"},
{id: 3, highlighted: false, text: "item3"},
];
var MyComponent = React.createClass({
render: function() {
return <div className={this.props.highlighted ? 'light-it-up' : ''}>{this.props.text}</div>;
}
});
var MyList = React.createClass({
toggleHighlight: function() {
this.props.items.forEach(function(v){
v.highlighted = !v.highlighted;
});
// Children must re-render
// IS THIS CORRECT?
this.setState({});
},
render: function() {
return <div>
<button onClick={this.toggleHighlight}>Toggle highlight</button>
{this.props.items.map(function(item) {
return <MyComponent key={item.id} text={item.text} highlighted={item.highlighted}/>;
})}
</div>;
}
});
React.render(<MyList items={items}/>, document.getElementById('container'));
这里的问题是你在this.props
而不是this.state
存储状态。 由于此组件正在改变items
,因此items
是 state 并且应该存储在this.state
。 (这是一篇关于 props 与 state的好文章。)这解决了您的渲染问题,因为当您更新items
您将调用setState
,它会自动触发重新渲染。
下面是你的组件使用 state 而不是 props 的样子:
var MyList = React.createClass({
getInitialState: function() {
return { items: this.props.initialItems };
},
toggleHighlight: function() {
var newItems = this.state.items.map(function (item) {
item.highlighted = !item.highlighted;
return item;
});
this.setState({ items: newItems });
},
render: function() {
return (
<div>
<button onClick={this.toggleHighlight}>Toggle highlight</button>
{ this.state.items.map(function(item) {
return <MyComponent key={item.id} text={item.text}
highlighted={item.highlighted}/>;
}) }
</div>
);
}
});
React.render( <MyList initialItems={initialItems}/>,
document.getElementById('container') );
请注意,我改名items
道具initialItems
,因为它清楚地表明, MyList
会发生变异它。 这是文档推荐的。
你可以在这里看到更新的小提琴: https : //jsfiddle.net/kxrf5329/
我找到了一个很好的解决方案,使用key属性重新渲染React Hook 。 如果我们更改了子组件或 React 组件的某些部分的关键属性,它将完全重新渲染。 当您需要重新渲染 React 组件的某些部分或重新渲染子组件时,它将使用它。 这是一个例子。 我将重新渲染完整的组件。
import React, { useState, useEffect } from "react";
import { PrEditInput } from "./shared";
const BucketInput = ({ bucketPrice = [], handleBucketsUpdate, mood }) => {
const data = Array.isArray(bucketPrice) ? bucketPrice : [];
const [state, setState] = useState(Date.now());
useEffect(() => {
setState(Date.now());
}, [mood, bucketPrice]);
return (
<span key={state}>
{data.map((item) => (
<PrEditInput
key={item.id}
label={item?.bucket?.name}
name={item.bucketId}
defaultValue={item.price}
onChange={handleBucketsUpdate}
mood={mood}
/>
))}
</span>
);
};
export default BucketInput;
重新渲染子项的一个简单选项是每次需要重新渲染时更新唯一的键属性。
<ChildComponent key={this.state.updatedKey}/>
您可以在子组件上设置数字键,并在执行操作后触发键更改。 例如
state = {
childKey: 7,
};
<ChildComponent key={this.state.childKey}/>
actionToTriggerReload = () => {
const newKey = this.state.childKey * 89; // this will make sure the key are never the same
this.setState({childKey: newKey})
}
这肯定会重新渲染 ChildComponent
在子组件中设置数字默认“键”并重新渲染只需更改键值。
this.state = {
updatedKey: 1,
};
triggerReload = () => {
let newKey = Math.floor(Math.random() * 100); // make sure the key are never the same
this.setState({updatedKey: newKey})
}
<childComponent key={this.state.updatedKey} handlerProp = {this.onClickItemEvent} />
这对我在 reactjs 类库中重新渲染 ChildComponent 有用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.