为什么在以下伪代码示例中,当Container更改foo.bar时,Child不会重新渲染?
Container {
handleEvent() {
this.props.foo.bar = 123
},
render() {
return <Child bar={this.props.foo.bar} />
}
Child {
render() {
return <div>{this.props.bar}</div>
}
}
即使forceUpdate()
在修改Container中的值后调用,Child仍会显示旧值。
更新子项以使其属性“键”等于名称。每次更改键时,组件都会重新渲染。
Child {
render() {
return <div key={this.props.bar}>{this.props.bar}</div>
}
}
因为如果父项的props发生变化,但是STATE的状态发生变化,则子项不会重新呈现:
您显示的是这样的:https :
//facebook.github.io/react/tips/communicate-between-components.html
它将通过道具将数据从父级传递到子级,但是那里没有重新渲染逻辑。
您需要为父级设置一些状态,然后在父级更改状态下重新渲染子级。这可能会有所帮助。
https://facebook.github.io/react/tips/expose-component-functions.html
我有同样的问题。这是我的解决方案,我不确定这是否是个好习惯,如果不是,请告诉我:
state = {
value: this.props.value
};
componentDidUpdate(prevProps) {
if(prevProps.value !== this.props.value) {
this.setState({value: this.props.value});
}
}
UPD:现在您可以使用React Hooks执行相同的操作:(仅当component是一个函数时)
const [value, setValue] = useState(propName);
// This will launch only if propName value has chaged.
useEffect(() => { setValue(propName) }, [propName]);
根据React哲学的组成部分,无法更改其道具。它们应该从父母那里收到,并且应该是不变的。只有父母可以改变孩子的道具。
关于状态与道具的很好的解释
另外,请阅读此线程为什么我不能在react.js中更新道具?
确认后,添加密钥即可。我浏览了文档以尝试并了解原因。
在创建子组件时,React希望高效。如果它与另一个子组件相同,则不会渲染新组件,这会使页面加载更快。
添加一个键会强制React渲染一个新组件,从而为该新组件重置State。
https://reactjs.org/docs/reconciliation.html#recursing-on-children
从functions
和创建React组件时useState
。
const [drawerState, setDrawerState] = useState(false);
const toggleDrawer = () => {
// attempting to trigger re-render
setDrawerState(!drawerState);
};
这确实不工作
<Drawer
drawerState={drawerState}
toggleDrawer={toggleDrawer}
/>
这不工作(添加键)
<Drawer
drawerState={drawerState}
key={drawerState}
toggleDrawer={toggleDrawer}
/>
您应该使用setState
功能。否则,无论您如何使用forceUpdate,state都不会保存您的更改。
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>
}
}
}
您的代码似乎无效。我无法测试此代码。
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}
/>
);
}
此示例用于useEffect
在更改时props
更改状态。
使用setState函数。所以你可以做
this.setState({this.state.foo.bar:123})
在handle事件方法中。
状态一旦更新,将触发更改,然后进行重新渲染。
如果不保持任何状态而只是渲染道具然后从父级调用它,则应该将Child用作功能组件。替代方法是,可以将钩子与功能组件(useState)一起使用,这将导致无状态组件重新呈现。
同样,您不应该更改道具,因为它们是不可变的。维护组件的状态。
Child = ({bar}) => (bar);
我遇到了同样的问题。我有一个Tooltip
正在接收showTooltip
道具的组件,我正在Parent
根据if
条件在组件上进行更新,它正在组件中进行更新,Parent
但Tooltip
组件未渲染。
const Parent = () => {
let showTooltip = false;
if(....){ showTooltip = true; }
return(
<Tooltip showTooltip={showTooltip}></Tooltip>
)
}
我正在做的错误是声明showTooltip
为let。
我意识到自己做错了我违反了渲染工作原理的工作,用钩子代替了工作。
const [showTooltip, setShowTooltip] = React.useState<boolean>(false);
在子组件的connect方法的mapStateToProps中定义更改的道具。
function mapStateToProps(state) {
return {
chanelList: state.messaging.chanelList,
};
}
export default connect(mapStateToProps)(ChannelItem);
就我而言,channelList的频道已更新,因此我在mapStateToProps中添加了chanelList
文章标签:html , javascript , reactjs
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!