繁体   English   中英

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

[英]React: How to set state of object property?

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

我一直在尝试允许用户使用复选框打开输入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>
  );
});

解决此问题的快速方法是修改将<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或在handleDesc内调用类似this.setState()的方法时,它将按预期工作。

有关“箭头功能”的微妙特征的更多信息, 请参见本文

更新

此外,考虑像这样更新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的源代码)中,它会看到问题在于,当this.state[name] === true时,您的<input />元素没有checked属性。 如果在this.state[name] === true情况下呈现的输入上应用一个checked={ 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>
 );

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

handleDesc = (event) => {

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM