为了账号安全,请及时绑定邮箱和手机立即绑定

React - 如何循环和更新对象模型中的值?

React - 如何循环和更新对象模型中的值?

波斯汪 2023-08-05 10:15:16
我有一个对象模型模式如下   this.state = {        data: {            audi: {                 engine: '2.5',                 gearbox: 'auto',                 fuel: 'petrol'             },             bmw: {                 engine: '3.0',                 gearbox: 'auto',                 fuel: 'petrol'             },             merc: {                 engine: '6.3',                 gearbox: 'manual',                 fuel: 'petrol'             }         }    }我的目标是:循环数据并渲染将 HTML 中的值更改映射到 this.state.data 对象中的相应键我没有使用数组,因为在发布它时它必须看起来像上面的对象模式。目前我正在尝试这样做://To renderObject.entries(this.state.data).map((x,index) =>    <p>x.key</p> //Trying to reach 'audi' with x.key    // Render each KPV in object    {x.key}: <input key={index} onChange={this.handleChange} value={x.value}/>)然后更新同一状态模型中的相应值:// To update the state model with changed valuessetData = (key, val) => {    this.setState(state => ({        data: {            ...state.data,            obj: { [key]: val },            //Don't know how to map to state properly!        }    }));};// Handle input changehandleChange = key => e => {    this.setData(key, e.target.value);};请任何人就这种方法向我提出建议,非常感谢:)
查看完整描述

3 回答

?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

首先,您需要正确渲染,这意味着循环所有键(汽车制造商),然后循环所有属性/值对。您可以使用解构数组来简化此操作


Object.entries(someObject).map( ([key,value]) => .... )

继承人渲染:


render() {

    return Object.entries(this.state.data).map(([maker, props]) => {

      return (

        <div>

          <h2>{maker}</h2>

          {Object.entries(props).map(([key, value], index) => {

            return (

              <div>

                {key}:{" "}

                <input

                  key={index}

                  onChange={this.handleChange(maker, key)}

                  defaultValue={value}

                />

              </div>

            );

          })}

        </div>

      );

    });

  }

您会注意到我更改了您的handleChange方法来传递汽车制造商和正在编辑的属性 - 这可以传递到setData:


// To update the state model with changed values

  setData = (maker, key, val) => {

    this.setState((state) => ({

      data: {

        ...state.data,

        [maker]: {

          ...state.data[maker],

          [key]: val

        }

        //Don't know how to map to state properly! Now you do!

      }

    }));

  };


  // Handle input change

  handleChange = (maker, key) => (e) => {

    this.setData(maker, key, e.target.value);

  };

实时工作示例:https ://codesandbox.io/s/react-playground-forked-dw9sg


查看完整回答
反对 回复 2023-08-05
?
繁星coding

TA贡献1797条经验 获得超4个赞

您首先没有从输入回调传递键和事件对象,您的代码应该是这样的,


显示逻辑在我看来是错误的,


Object.entries(this.state.data).map((x, index) =>

    /* 

     here x is an array and it looks like 

     ["audi", {engine: '2.5', gearbox: 'auto', fuel: 'petrol}

    */

     // You need to access the data in the second index

     // if you want to print each value of the object

    <p>x[1].engine</p>

    <p>x[1].gearbox</p>

    <p>x[1].fuel</p> 


    // Render each KPV in object

    {x[0]}: <input key={index} onChange={(e) => this.handleChange(x[0], e)} value={x[1].engine}/>

)

回调handleChange应该看起来像,不要柯里化它们。


handleChange = (key, e) => {

    this.setData(key, e.target.value);

};

我建议使用 lodash 的castArray之类的实用程序,https://lodash.com/docs/4.17.15#castArray将对象转换为数组,以便您可以轻松使用它。


查看完整回答
反对 回复 2023-08-05
?
杨__羊羊

TA贡献1943条经验 获得超7个赞

class App extends React.Component {

  constructor(props) {

    super(props)

    this.state = { 

      data: {

        audi: { model: "A7", transmission: "AT" },

        merc: { model: "GLA", transmission: "MT" },

        bmw: { model: "M3", transmission: "AT" },

      },

    }

  }

  update(make, detail, value) {

    let data = this.state.data

    data[make][detail] = value

    console.log(`Updating ${make} ${detail} with ${value}`)

    this.setState({ data: data })

  }

  handleChange(make, detail) {

    return e => { this.update(make, detail, e.target.value) }

  }

  renderDetails(details) {

    return details.map(d => (<div><span>{d.key}:</span> <input value={d.model} onChange={this.handleChange(d.key, "model")} /> <input value={d.transmission} onChange={this.handleChange(d.key, "transmission")} /></div>))

  }

  render() {

    const details = Object.entries(this.state.data).map(d => ({ key: d[0], ...d[1] }))

    return <div>{this.renderDetails(details)}</div>

  }

}


ReactDOM.render((<App />), document.getElementById("app"))

body { font-family: monospace; }

span { display: block; font-weight: bold; }

input { width: 50px; }

<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="app"></div>


查看完整回答
反对 回复 2023-08-05
  • 3 回答
  • 0 关注
  • 159 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信