Javascript 反应:为什么子组件不';道具更改时不更新
为什么在下面的伪代码示例中,当容器更改foo.bar时,子对象不重新呈现Javascript 反应:为什么子组件不';道具更改时不更新,javascript,html,reactjs,Javascript,Html,Reactjs,为什么在下面的伪代码示例中,当容器更改foo.bar时,子对象不重新呈现 Container { handleEvent() { this.props.foo.bar = 123 }, render() { return <Child bar={this.props.foo.bar} /> } Child { render() { return <div>{this.props.bar}</div> } } 容
Container {
handleEvent() {
this.props.foo.bar = 123
},
render() {
return <Child bar={this.props.foo.bar} />
}
Child {
render() {
return <div>{this.props.bar}</div>
}
}
容器{
handleEvent(){
this.props.foo.bar=123
},
render(){
返回
}
孩子{
render(){
返回{this.props.bar}
}
}
即使我在修改容器中的值后调用
forceUpdate()
,子对象仍会显示旧值。因为如果父对象的属性更改,但其状态更改,子对象不会重新渲染:)
您展示的是:
它将通过道具将数据从父级传递到子级,但没有重新渲染逻辑
您需要为父级设置一些状态,然后在父级更改状态时重新渲染子级。
这可能会有所帮助。
您应该使用
设置状态
功能。否则,状态将不会保存您的更改,无论您如何使用forceUpdate
Container {
handleEvent= () => { // use arrow function
//this.props.foo.bar = 123
//You should use setState to set value like this:
this.setState({foo: {bar: 123}});
};
render() {
return <Child bar={this.state.foo.bar} />
}
Child {
render() {
return <div>{this.props.bar}</div>
}
}
}
容器{
handleEvent=()=>{//使用箭头函数
//this.props.foo.bar=123
//您应该使用setState设置如下值:
this.setState({foo:{bar:123});
};
render(){
返回
}
孩子{
render(){
返回{this.props.bar}
}
}
}
您的代码似乎无效。我无法测试此代码。根据React哲学,组件无法更改其道具。它们应该从父级接收,并且应该是不可变的。只有父级可以更改其子级的道具 很好的解释 另外,阅读此线程,并使用setState函数。 所以你可以
this.setState({this.state.foo.bar:123})
在handle事件方法内部
更新状态后,它将触发更改,并将进行重新渲染。更新子级以使属性“key”等于名称。每次键更改时,组件都将重新渲染
Child {
render() {
return <div key={this.props.bar}>{this.props.bar}</div>
}
}
Child{
render(){
返回{this.props.bar}
}
}
我也有同样的问题。
这是我的解决方案,我不确定这是否是好的做法,如果不是,请告诉我:
state = {
value: this.props.value
};
componentDidUpdate(prevProps) {
if(prevProps.value !== this.props.value) {
this.setState({value: this.props.value});
}
}
UPD:现在,您可以使用React挂钩执行相同的操作:
(仅当组件是函数时)
如果子组件不维护任何状态,只需呈现道具,然后从父组件调用它,那么您可能应该将其作为功能组件。另一种选择是,您可以将挂钩与功能组件(useState)一起使用,这将导致无状态组件重新呈现 此外,您不应该更改PROPA,因为它们是不可变的。请维护组件的状态
Child = ({bar}) => (bar);
确认了,添加了一个关键点。我浏览了文档,试图了解原因 React希望在创建子组件时效率更高。如果新组件与另一个子组件相同,它将不会呈现新组件,这会加快页面加载速度 添加关键点将对渲染新组件作出反应,从而重置该新组件的状态
function mapStateToProps(state) {
return {
chanelList: state.messaging.chanelList,
};
}
export default connect(mapStateToProps)(ChannelItem);
我遇到了同样的问题。 我有一个
Tooltip
组件正在接收showTooltip
道具,我正在基于if
条件在Parent
组件上更新它,但是Tooltip
组件没有呈现
const Parent = () => {
let showTooltip = false;
if(....){ showTooltip = true; }
return(
<Tooltip showTooltip={showTooltip}></Tooltip>
)
}
从
函数
和使用状态
创建反应组件时
const [drawerState, setDrawerState] = useState(false);
const toggleDrawer = () => {
// attempting to trigger re-render
setDrawerState(!drawerState);
};
这不起作用
<Drawer
drawerState={drawerState}
toggleDrawer={toggleDrawer}
/>
此不起作用(添加键)
在子组件的连接方法的MapStateTrops中定义更改的道具
function mapStateToProps(state) {
return {
chanelList: state.messaging.chanelList,
};
}
export default connect(mapStateToProps)(ChannelItem);
在我的例子中,channelList的频道已更新,因此我在MapStateTops中添加了chanelList导出默认函数数据表({col,row}){
export default function DataTable({ col, row }) {
const [datatable, setDatatable] = React.useState({});
useEffect(() => {
setDatatable({
columns: col,
rows: row,
});
/// do any thing else
}, [row]);
return (
<MDBDataTableV5
hover
entriesOptions={[5, 20, 25]}
entries={5}
pagesAmount={4}
data={datatable}
/>
);
}
const[datatable,setDatatable]=React.useState({});
useffect(()=>{
可设置数据表({
栏目:col,
行:行,
});
///还有别的事吗
},[世界其他地区];
返回(
);
}
本例使用
useffect
在props
更改时更改状态。在我的例子中,我正在更新传递给组件的加载状态。在按钮中,props.load
按预期进行(从false切换为true)但是显示旋转器没有更新的三元数据
我尝试添加一个键,添加一个使用useffect()等更新的状态,但其他答案都不起作用
对我起作用的是改变这一点:
setLoading(true);
handleOtherCPUHeavyCode();
为此:
setLoading(true);
setTimeout(() => { handleOtherCPUHeavyCode() }, 1)
我想这是因为handleOtherCPUHeavyCode中的过程非常繁重和密集,因此应用程序会冻结一秒钟左右。添加1ms超时可以更新加载布尔值,然后繁重的代码函数就可以完成它的工作。我的案例涉及到在props对象上有多个属性,并且需要重新加载在给孩子换衣服的时候告诉他。
上面提供的解决方案是可行的,但为每个解决方案添加一个密钥变得单调乏味(想象一下有15个…)。如果有人面临这一问题,您可能会发现将道具对象字符串化很有用:
<Child
key={JSON.stringify(props)}
/>
这样,道具上每个属性的每次更改都会触发子组件的重新渲染
function mapStateToProps(state) {
return {
chanelList: state.messaging.chanelList,
};
}
export default connect(mapStateToProps)(ChannelItem);
希望对某人有所帮助。您一定使用过动态组件。
在这个代码片段中,我们多次呈现子组件,并传递键
- 如果我们多次动态呈现一个组件,那么React不会呈现该组件,直到它的键被更改
如果使用setState方法更改选中的。在更改子组件的键之前,它不会反映在子组件中。我们必须在子组件的状态下保存它,然后相应地更改它以渲染子组件
类父级扩展组件{
状态={
核对:正确
}
render(){
返回(
{
[1,2,3]。地图(
<Child
key={JSON.stringify(props)}
/>
componentWillReceiveProps({bar}) {
this.setState({...this.state, bar})
}