React:如何设置对象属性的状态?

时间:2018-10-08 22:18:50

标签: javascript reactjs

我是React的初学者,我一直在使用NPM软件包react-    标签以在我的网站上显示标签。

我一直在尝试允许    用户可以使用复选框打开输入type = text标签来更新其个人资料的描述,从而允许用户输入自己的个人资料详细信息。

但是,我正在努力使用handleDesc函数设置选项卡的描述状态。我不确定如何更新每个选项卡的描述状态。我不断收到错误消息“组件正在将复选框的受控输入更改为不受控制”。

有人可以帮助我吗?

class EditSite extends React.Component {
constructor(props) {
    super(props);
    this.state = {About: true,
        "Opening Hours": true,
        Contact: true,
        Menu: false,
        Offers: false,
        "External Links": true,
        tabOptions: {
            About: {desc:'1'},
            "Opening Hours": {desc: '2'},
            Contact: {desc:'3'},
            Menu: {desc:'4'},
            Offers: {desc:'5'},
            "External Links": {desc:'6'},
            }
        }

下面是我正在努力设置描述状态的函数(handleDesc)。

handleDesc = (event) => {
    let tabOptions = {...this.state.tabOptions[event.target.name]};
    tabOptions = event.target.value;
    console.log(tabOptions);
    this.setState({tabOptions: [event.target.name]});
}   

 render() {
    const links = [];
    const tabs = [];
    const tabPanels = [];

第二个输入标签是我希望用户能够将其自己的详细信息添加到特定选项卡的地方。

Object.keys(this.state.tabOptions).forEach(name => {
  links.push(
      <div>
      <label key={name}>{name}</label>
      <input
        type="checkbox"
        checked={this.state[name]}
        name={name}
        onChange={this.handleCheckClicked}
      />
      { this.state[name] === true ? (
      <input
      name={name}
      type='text'
      onChange={this.handleDesc}
      />
      ) : null }
      </div>
  );

  if (!this.state[name]) return;

  const { desc } = this.state.tabOptions[name];

  tabs.push(
    <Tab>
      <h3>{name}</h3>
    </Tab>
  );

  tabPanels.push(
    <TabPanel> 
        {desc}
    </TabPanel>
  );
});

2 个答案:

答案 0 :(得分:0)

一种解决此问题的快速方法是修改将<input />元素的onChange处理程序绑定到以下代码:

links.push(
      <div>
      <label key={name}>{name}</label>
      <input
        type="checkbox"
        checked={this.state[name]}
        name={name}
        onChange={ (event) => this.handleCheckClicked(event) /* <-- update this also */ }
      />
      { this.state[name] === true ? (
      <input
      name={name}
      type='text'
      onChange={ (event) => this.handleDesc(event) /* [ UPDATE HERE ] */ } 
      />
      ) : null }
      </div>
  );

通过这样声明内联箭头功能:

onChange={ (event) => this.handleDesc(event) }

它将handleDesc函数的上下文设置为<EditSite />组件(当前,上下文将是全局window对象)。这意味着,当您访问this.state或在this.setState()内部调用类似handleDesc的方法时,它将按预期工作。

有关“箭头功能” see this article的微妙特征的更多信息。

更新

此外,考虑更新您的handleDesc方法,以正确地改变状态:

handleDesc = (event) => {
    let tabOptions = {...this.state.tabOptions[event.target.name]};
    tabOptions = event.target.value;
    console.log(tabOptions);
    this.setState({tabOptions}); // <--- Update this line
}  

更新2

在进一步研究中(进入React的源代码),它会看到问题在于,当<input />满足时,您的checked元素没有this.state[name] === true属性。如果您在checked={ true }情况下呈现的输入上应用this.state[name] === true的虚拟属性/值对,则此警告消息应停止显示:

links.push(
  <div>
  <label key={name}>{name}</label>
  <input
    type="checkbox"
    checked={this.state[name]}
    name={name}
    onChange={this.handleCheckClicked}
  />
  { this.state[name] === true ? (
  <input
  name={name}
  type='text'
  checked={ true } /* <-- Update this line, don't include this comment in code */
  onChange={this.handleDesc}
  />
  ) : null }
  </div>
 );

答案 1 :(得分:0)

SetState需要一个新对象。因此,无法通过这种方式仅设置嵌套对象的属性。您可以做的就是复制tabOptions并更改所需的属性,然后再将其传递给setState。

示例

handleDesc = (event) => {

const newTabOptions = {
  ...this.state.tabOptions,
  [event.target.name]: {desc: event.target.value}

this.setState({tabOptions: newTabOptions});
}