![](/img/trans.png)
[英]React js, why doesn't my component re-render when I change the value of open?
[英]Why doesn't my React child component get value (re-render) when I change the parent state?
背景
我写了一个带有嵌套子组件的父组件的精确、简短但完整的示例,它只是尝试:
this.state.name
) 这是应用程序加载时的样子, default value
从 Parent state 传递给 child 道具。
更改名称
我想要做的就是在用户在父级的<input>
中添加新名称并单击父级的<button>
后允许更改名称
但是,如您所见,当用户单击按钮时,只会再次呈现 Parent。
这是所有源代码,您可以在我的 StackBlitz 项目中查看和试用。
我尽量保持简单。
父组件( DataLoader
)
import * as React from 'react';
import { useState } from 'react';
import { Grid } from './Grid.tsx';
interface LoaderProps {
name: string;
}
export class DataLoader extends React.Component<LoaderProps, {}> {
state: any = {};
constructor(props: LoaderProps) {
super(props);
this.state.name = this.props.name;
this.changeName = this.changeName.bind(this);
}
render() {
const { name } = this.state;
let parentOutput = <span>{name}</span>;
return (
<div>
<button onClick={this.changeName}>Change Name</button>
<input id="mapvalue" type="text" placeholder="name" />
<hr id="parent" />
<div>### Parent ###</div>
<strong>Name</strong>: {parentOutput}
<hr id="child" />
<Grid childName={name} />
</div>
);
}
changeName() {
let newValue = document.querySelector('#mapvalue').value.toString();
console.log(newValue);
this.setState({
name: newValue,
});
}
}
子组件( Grid
)
import * as React from 'react';
interface PropsParams {
childName: string;
}
export class Grid extends React.Component<PropsParams, {}> {
state: any = {};
constructor(props: PropsParams) {
super(props);
let counter = 0;
this.state = { childName: this.props.childName };
console.log(`CHILD -> this.state.name : ${this.state.childName}`);
}
render() {
const { childName } = this.state;
let mainChildOutput = <span>{childName}</span>;
return (
<div>
<div>### Child ####</div>
<strong>Name</strong>: {mainChildOutput}
</div>
);
}
}
App.tsx的设置如下——这是 props 的默认值
import * as React from 'react';
import { DataLoader } from './DataLoader.tsx';
import './style.css';
export default function App() {
return (
<div>
<DataLoader name={'default value'} />
</div>
);
}
您会看到两个不同的值,因为您正在跟踪两个不同的状态。 一个在父组件中,一个在子组件中。
不要重复数据。
如果子组件应该始终显示传递给它的道具,那么不要在子组件中跟踪 state,只显示传递给它的道具。 例如:
export class Grid extends React.Component<PropsParams, {}> {
render() {
const { childName } = this.props; // <--- read the value from props, not local state
let mainChildOutput = <span>{childName}</span>;
return (
<div>
<div>### Child ####</div>
<strong>Name</strong>: {mainChildOutput}
</div>
);
}
}
在 Child 组件中,您仅在构造函数中将 prop childName
值设置为 state。 构造函数仅在安装组件时执行。 因此,它不知道childName
prop 是否稍后更改。
有 2 个解决方案。
(1) 直接使用this.props.childName
,不设置为state。
(2) 添加一个useEffect
,在 prop 更改时更新 state 值。
React.useEffect(() => {
this.state = {
childName: this.props.childName;
};
}, [this.props.childName]);
但是,我推荐第一种解决方案,因为复制数据不是一个好习惯。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.