gpt4 book ai didi

javascript - 如何正确设置子组件和父组件的状态?

转载 作者:行者123 更新时间:2023-12-01 01:19:07 24 4
gpt4 key购买 nike

在下面的示例中,我尝试执行以下操作:

  • 我有输入字段,我想以以下形式捕获对对象中这些输入所做的更改:{ id: value, id: value, ...etc },我可以然后将此数据结构发送到服务来执行...无论什么:)

我在实现时遇到问题:

  • Input组件的输入字段发生变化时,我需要通过setState管理onChange,这是React中的典型做法。但是,我还需要捕获对输入字段所做的更改。
  • 为了捕获更改,我使用组件来处理回调函数,该函数将使用新更改更新状态。
  • 此外,我只允许用户在存在新更改的情况下提交更改。现在保持简单,当存在新更改时启用一个按钮。

TLDR:我认为我使用的设置状态有问题,我试图通过回调函数在子级和父级中设置状态。然而,一个优先于另一个,两个设置状态都不会执行。这是为什么?如何正确实现?

注意:这是伪代码,请原谅任何拼写错误,我尽力保持真实。

  • 提交组件
class Submit extends React.Component {
constructor(props) {
super(props);
}

render() {
const { showButton } = this.props;

return (
<button type='button' disabled={!showButton}>
Hello world!
</button>
);
}

);
  • 输入组件
class Input extends React.Component {
constructor(props) {
super(props);

this.state = {
name: ''
};
}

handleChange = (e) => {
const { enable } = this.props;
const id = e.target.id;
const value = e.target.value;

this.setState({
[id]: value
});

enable(id, value); // <- Using this here breaks set state.
}

render() {
const { myName } = this.state;

return (
<div>
<input type='text' id='name' onChange={this.handleChange} placeholder='' />
<input type='text' id='address' onChange={this.handleChange} placeholder='' />
<!-- there can be more input fields -->
</div>
);
}
}
  • 父组件
class Parent extends React.Component {
constructor(props) {
super(props);

this.state = {
enableButton: false,
inputFieldValues: {},
};
}

enable = (value) => {
const { inputFieldValue } = this.state;
let changes = inputFieldValues || {};

changes[key] = value;

this.setState({
enableButton: true,
inputFieldValues: changes
});
}

render() {
const { enableButton } = this.state;

return (
<div>
<Input enable={this.enable} />
<Submit enableButton={enableButton} />
</div>
);
}
}

最佳答案

我不太确定我是否理解了你的问题,但这里是你的伪代码的固定示例。

我注意到的:

const { inputFieldValue } = this.state;
let changes = inputFieldValues || {};

changes[key] = value;

我不知道你是否在真实的应用程序中犯了同样的错误,但我想提一下,这是一个非常粗鲁的错误,可能会导致意外的行为,因为你改变了状态对象,而不是创建新的状态对象。 React 会比较对象引用,但不会对它们进行深入检查。这个let changes = inputFieldValues || {};应该是let changes = { ...inputFieldValues } || {}; .

此外,您没有为输入提供字段值。虽然它不会影响状态更改,但输入和状态可能会变得不同步。

class Submit extends React.Component {
constructor(props) {
super(props);
}

render() {
const { enableButton } = this.props;

return (
<button type="button" disabled={!enableButton}>
Hello world!
</button>
);
}
}

class Input extends React.Component {
constructor(props) {
super(props);

this.state = {
name: "",
address: ""
};
}

handleChange = e => {
const { enable } = this.props;
const id = e.target.id;
const value = e.target.value;

this.setState({
[id]: value
});

enable(id, value);
};

render() {
const { myName } = this.state;

console.log("Input:", this.state);

return (
<div>
<input
type="text"
id="name"
onChange={this.handleChange}
placeholder=""
{/* Always provide state values to your inputs to make sure they're always synchronized */}
value={this.state.name}
/>
<input
type="text"
id="address"
onChange={this.handleChange}
placeholder=""
value={this.state.address}
/>
</div>
);
}
}

class Parent extends React.Component {
constructor(props) {
super(props);

this.state = {
enableButton: false,
inputFieldValues: {}
};
}

enable = (key, value) => {
const { inputFieldValues } = this.state;
// Copy objects, when you change their fields.
let changes = { ...inputFieldValues } || {};

changes[key] = value;

this.setState({
enableButton: true,
inputFieldValues: changes
});
};

render() {
const { enableButton } = this.state;

console.log("Parent:", this.state);

return (
<div>
<Input enable={this.enable} />
<Submit enableButton={enableButton} />
</div>
);
}
}

ReactDOM.render(<Parent />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>

关于javascript - 如何正确设置子组件和父组件的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54409899/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com