【发布时间】:2020-01-28 19:37:25
【问题描述】:
我正在开发一个 reactjs 网站,该网站将包含一组项目来填充表格。
父 shell 会将可用记录列表下拉到一个数组中 -- 并使用一个子组件,我想用这些数据填充表格行。
我已经开始创建子组件 - 但是直到我将状态处理放置在渲染函数附近才处理由父组件提供的属性。
我在子组件设置状态中确实有一个构造函数,但它没有看到要走的路——我应该在 componetDidMount 还是 componentWillMount 中设置状态(——如果创建了新的子组件?)
子组件将具有按钮——保存、生成、取消——然后需要更改初始加载状态 -
//规则 父母可以从数组中创建/删除孩子—— 孩子需要获取父母给定的初始值 - 但随后独立于它行事 - 因此孩子可以获取初始属性,然后使用其中的按钮 - 进行自己的调用。应用程序已经被这个父数组绑定,这会导致故障。
-- 孩子需要能够取消 - 例如在保存之前恢复到其原始状态 - 所以如果它被触摸 - isDirty 则为真。 -- 一个老孩子 - isNew: false - 预先存在的数据 - 只显示一个保存按钮。只有名称是可编辑的 -- 一个新的孩子 -- isNew: true -- 首先会显示一个生成按钮(保存隐藏) -- 如果用户手动开始在名称字段中输入数据,生成按钮将被隐藏并显示保存。 -- 在用户选择区域之前,生成/保存按钮将被禁用。
https://codesandbox.io/embed/frosty-vaughan-kdl1v 应该看起来像这样——一旦初始数组生成了孩子——父母应该只能添加空白孩子或删除新/旧孩子——所有其他状态应该只发生在孩子级别——因为你可能有 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 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>
);
}
}
//2019 年 9 月 30 日最新 https://codesandbox.io/embed/elated-raman-twdqr
^ 将添加/删除子节点 -- 为后端删除模拟 db 数组
//2019 年 10 月 1 日最新 https://codesandbox.io/s/stupefied-hodgkin-iyj43 - 最新版本 - 更稳定
【问题讨论】:
-
为什么你甚至需要孩子的状态?正如 React 开发人员 here 所提到的,从 props 派生状态是一个坏主意。
-
子组件需要能够修改自己的状态——子组件中会有按钮来进行 api 调用以切换数据内联
-
codesandbox.io/s/stupefied-hodgkin-iyj43 - 最新版本 - 更稳定
-
@TheOldCounty,你能用最新的更新你的问题吗?
标签: reactjs