Reactjs——每个组件的父、子状态处理体系结构
我正在开发一个reactjs网站,该网站将提供一个项目数组来填充一个表 父shell将把一个可用记录列表拉入一个数组中——我想使用一个子组件用这个数据填充表行 我已经开始创建子组件-但是父组件提供的属性没有被处理,直到我将状态处理放在渲染函数附近 我确实在子组件设置状态中有一个构造函数,但它没有看到前进的方向——我应该在ComponentDidMount或componentWillMount中设置状态(--如果生成了新的子组件?) 子组件将有按钮——保存、生成、取消——需要更改初始加载状态- //规则 父级可以从数组中创建/删除子级-- 子级需要获取父级给定的初始值,但随后独立于父级执行操作,这样子级就可以获取初始属性,然后使用其中的按钮进行自己的调用。应用程序已被此父数组绑定,这会导致故障 --孩子需要能够取消-例如,恢复到保存前的原始状态-因此,如果其触碰-isDirty为真。 --旧的子项-isNew:false-预先存在的数据-仅显示保存按钮。只有名称是可编辑的 --新的子级--isNew:true--首先将显示一个生成按钮(保存隐藏)--如果用户手动开始在名称字段中输入数据,则生成按钮将隐藏并显示保存。-在用户选择区域之前,生成/保存按钮处于禁用状态 应该是这样的--一旦初始数组生成了子级--父级应该只能添加空白子级或删除新/旧子级--所有其他状态应该只发生在子级--因为您可能有3个新的子级,5个旧的--开始更改值--有些已保存,有些被取消了-独立的更改 母公司Reactjs——每个组件的父、子状态处理体系结构,reactjs,Reactjs,我正在开发一个reactjs网站,该网站将提供一个项目数组来填充一个表 父shell将把一个可用记录列表拉入一个数组中——我想使用一个子组件用这个数据填充表行 我已经开始创建子组件-但是父组件提供的属性没有被处理,直到我将状态处理放在渲染函数附近 我确实在子组件设置状态中有一个构造函数,但它没有看到前进的方向——我应该在ComponentDidMount或componentWillMount中设置状态(--如果生成了新的子组件?) 子组件将有按钮——保存、生成、取消——需要更改初始加载状态- /
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>
);
}
}