Reactjs——每个组件的父、子状态处理体系结构

Reactjs——每个组件的父、子状态处理体系结构,reactjs,Reactjs,我正在开发一个reactjs网站,该网站将提供一个项目数组来填充一个表 父shell将把一个可用记录列表拉入一个数组中——我想使用一个子组件用这个数据填充表行 我已经开始创建子组件-但是父组件提供的属性没有被处理,直到我将状态处理放在渲染函数附近 我确实在子组件设置状态中有一个构造函数,但它没有看到前进的方向——我应该在ComponentDidMount或componentWillMount中设置状态(--如果生成了新的子组件?) 子组件将有按钮——保存、生成、取消——需要更改初始加载状态- /

我正在开发一个reactjs网站,该网站将提供一个项目数组来填充一个表

父shell将把一个可用记录列表拉入一个数组中——我想使用一个子组件用这个数据填充表行

我已经开始创建子组件-但是父组件提供的属性没有被处理,直到我将状态处理放在渲染函数附近

我确实在子组件设置状态中有一个构造函数,但它没有看到前进的方向——我应该在ComponentDidMount或componentWillMount中设置状态(--如果生成了新的子组件?)

子组件将有按钮——保存、生成、取消——需要更改初始加载状态-

//规则 父级可以从数组中创建/删除子级-- 子级需要获取父级给定的初始值,但随后独立于父级执行操作,这样子级就可以获取初始属性,然后使用其中的按钮进行自己的调用。应用程序已被此父数组绑定,这会导致故障

--孩子需要能够取消-例如,恢复到保存前的原始状态-因此,如果其触碰-isDirty为真。 --旧的子项-isNew:false-预先存在的数据-仅显示保存按钮。只有名称是可编辑的 --新的子级--isNew:true--首先将显示一个生成按钮(保存隐藏)--如果用户手动开始在名称字段中输入数据,则生成按钮将隐藏并显示保存。-在用户选择区域之前,生成/保存按钮处于禁用状态

应该是这样的--一旦初始数组生成了子级--父级应该只能添加空白子级或删除新/旧子级--所有其他状态应该只发生在子级--因为您可能有3个新的子级,5个旧的--开始更改值--有些已保存,有些被取消了-独立的更改

母公司

import React, { Component } from "react";

import Child from "./Child";
export default class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [
        {
          name: "apple",
          currentCode: "BJ3343",
          previousCode: " ",
          region: "opt2",
          isNew: false,
          isDirty: false
        },
        {
          name: "cherry",
          currentCode: "AS3433",
          previousCode: " ",
          region: "opt1",
          isNew: false,
          isDirty: false
        }
      ]
    };
  }

  addChild() {
    let blank = {
      name: "xxxxxxxxxxxxxxx",
      code: "",
      region: "",
      isNew: true,
      isDirty: true
    };

    this.state.list.push(blank);
  }

  render() {
    return (
      <div>
        <button onClick={this.addChild()}>Add Child</button>
        <button>Remove Child</button>
        <table>
          <thead>
            <tr>
              <td />
              <td>Region</td>
              <td>Code</td>
              <td>Name</td>
              <td>save/generate</td>
              <td>cancel</td>
            </tr>
          </thead>
          <tbody>
            {this.state.list.map((item, index) => {
              return (
                <Child
                  key={index}
                  index={index}
                  item={item}
                />
              );
            })}
          </tbody>
        </table>
      </div>
    );
  }
}
import React,{Component}来自“React”;
从“/Child”导入子项;
导出默认类父扩展组件{
建造师(道具){
超级(道具);
此.state={
名单:[
{
名称:“苹果”,
当前代码:“BJ3343”,
以前的代码:“”,
区域:“opt2”,
isNew:错,
isDirty:错
},
{
姓名:“樱桃”,
当前代码:“AS3433”,
以前的代码:“”,
地区:“opt1”,
isNew:错,
isDirty:错
}
]
};
}
addChild(){
让空白={
名称:“XXXXXXXXXX”,
代码:“,
地区:“,
是的,
是的
};
this.state.list.push(空白);
}
render(){
返回(
添加子项
除去孩子
区域
代码
名称
保存/生成
取消
{this.state.list.map((项,索引)=>{
返回(
);
})}
);
}
}
孩子

//从“react dom”导入ReactDOM;
从“React”导入React,{Component};
导出默认类子扩展组件{
生成代码=索引=>{
//执行api调用,然后成功更改代码的值
//在此处进行api调用,并假设api调用返回代码213
常数响应代码=231;
返回响应代码;
};
saveCode=index=>{
//执行一个api调用——如果成功,则使子对象isDirty:false,isNew:false
};
取消=索引=>{
//还原此子项的状态
};
render(){
const index=this.props.index;
const{name,region,currentCode,isNew,isDirty}=this.props.item;
返回(
挑选
opt1
opt2
opt3
opt4
{" "}
this.generateCode(index)}>Generate
this.saveCode(index)}>Save
这个.cancel(index)}>cancel
);
}
}
//最迟于2019年9月30日

^将为后端添加/删除子项--要删除的模拟数据库数组

//最迟于2019年10月1日
-最新版本-更稳定

您需要将状态向上移动到父级,并从父级访问子级中的状态,如更新的答案所示。更多细节可以在这里找到。或者你可以使用集中的州管理图书馆,如或

类父级扩展React.Component{
//在此处定义父级和子级状态。
陈述={
parentState={…},
childState={name:'',区域:'}
}
handleChange=(新值)=>{
this.setState({childState:newValues});
//在此处获取数据并将其更新为状态
fetch(){}
}
componentDidMount(){
//在这里获取副作用,如数据fecthing和使用setState在这里设置state isLoading false
}
render(){
if(此.state.isLoading){
返回(
装载

) } 返回( { this.state.cart.map((项,键)=> ); } ); } } 类父类扩展了React.Component{ render(){ //使用道具而不是状态直接访问数据 //通过此.props.handleChange(newValue)将更新后的值向上传递给父级(取决于您的实现) //通过this.props.childState在下一次渲染中访问子对象中的新值 返回( 名称:{this.props.values.Name}

区域:{this.props.values.Region}

); } }
为什么您甚至需要孩子的状态?正如react开发者所提到的,从道具派生状态是个坏主意
//import ReactDOM from 'react-dom';
import React, { Component } from "react";

export default class Child extends Component {
  generateCode = index => {
    //does an api call -- and then on success alters the value of the code
    //Make an api call here and suppose api call return code 213
    const responseCode = 231;
    return responseCode;
  };

  saveCode = index => {
    //does an api call -- and then on success makes the child isDirty: false, isNew: false
  };

  cancel = index => {
    //reverts states for this child
  };

  render() {
    const index = this.props.index;
    const { name, region, currentCode, isNew, isDirty } = this.props.item;

    return (
      <tr>
        <td>
          <input type="checkbox" name="selection" />
        </td>
        <td>
          <select disabled={!isNew} type="input" name="region" value={region}>
            <option value="">Select</option>
            <option value="opt1">opt1</option>
            <option value="opt2">opt2</option>
            <option value="opt3">opt3</option>
            <option value="opt4">opt4</option>
          </select>
        </td>
        <td>
          <input disabled={!isNew} type="input" value={currentCode} />{" "}
        </td>
        <td>
          <input type="input" name="name" value={name} />
        </td>
        <td>
          <button onClick={() => this.generateCode(index)}>Generate</button>
          <button onClick={() => this.saveCode(index)}>Save</button>
        </td>

        <td>
          <button onClick={() => this.cancel(index)}>Cancel</button>
        </td>
      </tr>
    );
  }
}
class Parent extends React.Component {
//define your parent as well as child state here. 
state={
  parentState={...},
  childState={name: '', region: ''}
}

handleChange = (newValues) => {
  this.setState({childState: newValues});
  // fetch data here and update it to the state
  fetch(){}
}

componentDidMount(){
  //fetch side effects here like data fecthing and setting state isLoading false here using setState
}

render() {
  if (this.state.isLoading){
    return (
      <p>Loading</p>
    )
  }
  return (
    <div>
      {
        this.state.cart.map((item, key) =>
            <Child key={item.id}
                name=item.name
                region=item.region
                values: {this.state.childState}
                handleChange={this.handleChange}
            />
        );
      }
    </div>
  );
}
}


class Parent extends React.Component {
render() {
  // directly access data using props instead of state
  // pass the updated value upwards to the parent via this.props.handleChange(newValue)(depends on your implementation)
  // Access new value in the child in next render by this.props.childState
  return (
    <div>
      <p>Name: {this.props.values.name}</p>
      <p>Region: {this.props.values.region}</p>
    </div>
  );
}
}