我有以下超简单组件:
export default class Editor extends Component {
constructor(props) {
super(props);
this.state = { field: "Some Initial Text" };
this.handleChangeField = this.handleChangeField.bind(this);
}
handleChangeField(e) {
this.setState({field: e.target.value});
}
render() {
return (
<div>
<input type="text" name="word" value={this.state.field} onChange={this.handleChangeField} />
{this.state.field}
</div>
);
}
}
它只有一个字段。用户可以编辑该字段。根据用户在同级组件中单击的内容,上述组件将收到一个名为fieldValue
的道具,然后该道具将在输入字段中显示。由于用户应该能够编辑此输入字段,因此我不能简单地将prop直接放入输入字段中,而要使用状态。因此,我从道具初始化了组件状态。
但是,即使在组件初始化后,此道具也可能会更改。也就是说,它不仅是一个初始值,而且在运行时可能会更改,具体取决于用户在同级组件中单击的内容。
在不赞成使用ComponentWillReceiveProps
的情况下,如何在React 16.3中解决类似问题?我曾尝试研究GetDerivedStateFromProps
,但我不完全了解如何使用它。
答案 0 :(得分:1)
我不会尝试同步uncontrolled component with controlled component,因为当组件扩展时,逻辑可能会变得疯狂。
话虽如此,如果您真的想跟踪道具更改并相应地更新状态,则可以使用componentDidUpdate,但请确保在更新状态之前已获得一些有效条件。
这是一个正在运行的示例:
zip -r -9 /tmp/export.zip lib64/python3.6/site-packages/* lib64/python3.6/site-packages/.*
zip -r -9 /tmp/export.zip lib/python3.6/site-packages/* lib/python3.6/site-packages/.*
zip -r -9 /tmp/export.zip main.py
class Editor extends React.Component {
state = { field: this.props.defaultValue };
componentDidUpdate(prevProps) {
const { defaultValue } = this.props;
if (prevProps.defaultValue !== defaultValue) {
this.setState({ field: defaultValue });
}
}
handleChangeField = (e) => {
this.setState({ field: e.target.value });
}
render() {
return (
<div>
<input type="text" name="word" value={this.state.field} onChange={this.handleChangeField} />
{this.props.defaultValue}
</div>
);
}
}
class App extends React.Component {
state = { value: 'A default value' }
handleChange = ({ target }) => this.setState({ value: target.value })
render() {
const { value } = this.state;
return (
<div>
<h3>App </h3>
<input type="text" value={value} onChange={this.handleChange} />
<hr />
<h3>Editor</h3>
<Editor defaultValue={value} />
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
答案 1 :(得分:-1)
这非常简单,这是一个应该可以工作的原型:
export default class Editor extends Component {
static getDerivedStateFromProps(props, state) {
// You need to return object that will be used to fill the state, not manipulate the state itself
return {
field: state.field
}
}
constructor(props) {
super(props);
this.handleChangeField = this.handleChangeField.bind(this);
}
handleChangeField(e) {
this.setState({field: e.target.value});
}
render() {
return (
<div>
<input type="text" name="word" value={this.state.field} onChange={this.handleChangeField} />
{this.state.field}
</div>
);
}
}