React - Table 具有动态更新父状态的输入。逻辑问题
React - Table with inputs that dynamically updates parent state. Logical issue
我是 React 开发的新手,不幸的是,我仍然像 AngularJS 开发人员一样思考。我想使用子 table 组件更新应用程序状态数据。我开发了一个如下所示的基本解决方案,但我不确定我的解决方案是否有效。如果你向我推荐一些材料来学习 ReactJS 的基本哲学,那也会很棒。感谢您的任何建议。
class App extends React.Component {
constructor(){
super();
this.state = {
data:
[
{
"id":1,
"name":"Foo",
"age":"20"
},
{
"id":2,
"name":"Bar",
"age":"30"
},
{
"id":3,
"name":"Baz",
"age":"40"
}
]
}
this.updateState = this.updateState.bind(this);
}
updateState(e){
const cpy = this.state.data.slice();
this.setState({data:cpy});
}
render() {
return <div className="App">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<th>Id</th>
<th>Name</th>
<th>Age</th>
<th>Updated Name</th>
</thead>
<tbody>
{
this.state.data.map((x,i) => <TableRow key={i} data={x} updateHandler={this.updateState}></TableRow>)
}
</tbody>
</table>
</div>
</div>;
}
}
class TableRow extends React.Component{
constructor(){
super();
this.updateInput = this.updateInput.bind(this);
}
updateInput(e){
this.props.data.name = e.target.value;
this.props.updateHandler();
}
render(){
return <tr>
<td>{this.props.data.id}</td>
<td>{this.props.data.name}</td>
<td>{this.props.data.age}</td>
<td><input type="text" value={this.props.data.name} onChange={this.updateInput} /></td>
</tr>
}
}
ReactDOM.render(
<App/>,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
我建议查看官方 reactjs.org 网站上的文档。
至于你的代码,我认为你犯的主要错误是你在 TableRow 组件 updateInput 方法中改变了你的道具:
this.props.data.name = e.target.value;
这不是您在 React 中处理变化数据的方式。我建议这样:
import React, { Component } from "react";
class App extends Component {
state = {
data: [
{
id: 1,
name: "Foo",
age: "20"
},
{
id: 2,
name: "Bar",
age: "30"
},
{
id: 3,
name: "Baz",
age: "40"
}
]
};
handleNameUpdate = (id, name) => {
const { data } = this.state;
const newData = data.map(row => {
if (row.id === id) {
return {
...row,
name
};
}
return row;
});
this.setState({ data: newData });
}
render() {
return (
<div className="App">
<div className="table-responsive">
<table className="table table-hover">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Age</th>
<th>Updated Name</th>
</tr>
</thead>
<tbody>
{this.state.data.map(row => (
<TableRow
key={row.id}
data={row}
onNameUpdate={this.handleNameUpdate}
/>
))}
</tbody>
</table>
</div>
</div>
);
}
}
class TableRow extends Component {
handleChange = e => {
this.props.onNameUpdate(this.props.data.id, e.target.value);
};
render() {
const {
data: { id, name, age }
} = this.props;
return (
<tr>
<td>{id}</td>
<td>{name}</td>
<td>{age}</td>
<td>
<input type="text" value={name} onChange={this.handleChange} />
</td>
</tr>
);
}
}
export default App;
希望对您有所帮助!祝你好运!
我是 React 开发的新手,不幸的是,我仍然像 AngularJS 开发人员一样思考。我想使用子 table 组件更新应用程序状态数据。我开发了一个如下所示的基本解决方案,但我不确定我的解决方案是否有效。如果你向我推荐一些材料来学习 ReactJS 的基本哲学,那也会很棒。感谢您的任何建议。
class App extends React.Component {
constructor(){
super();
this.state = {
data:
[
{
"id":1,
"name":"Foo",
"age":"20"
},
{
"id":2,
"name":"Bar",
"age":"30"
},
{
"id":3,
"name":"Baz",
"age":"40"
}
]
}
this.updateState = this.updateState.bind(this);
}
updateState(e){
const cpy = this.state.data.slice();
this.setState({data:cpy});
}
render() {
return <div className="App">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<th>Id</th>
<th>Name</th>
<th>Age</th>
<th>Updated Name</th>
</thead>
<tbody>
{
this.state.data.map((x,i) => <TableRow key={i} data={x} updateHandler={this.updateState}></TableRow>)
}
</tbody>
</table>
</div>
</div>;
}
}
class TableRow extends React.Component{
constructor(){
super();
this.updateInput = this.updateInput.bind(this);
}
updateInput(e){
this.props.data.name = e.target.value;
this.props.updateHandler();
}
render(){
return <tr>
<td>{this.props.data.id}</td>
<td>{this.props.data.name}</td>
<td>{this.props.data.age}</td>
<td><input type="text" value={this.props.data.name} onChange={this.updateInput} /></td>
</tr>
}
}
ReactDOM.render(
<App/>,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
我建议查看官方 reactjs.org 网站上的文档。
至于你的代码,我认为你犯的主要错误是你在 TableRow 组件 updateInput 方法中改变了你的道具:
this.props.data.name = e.target.value;
这不是您在 React 中处理变化数据的方式。我建议这样:
import React, { Component } from "react";
class App extends Component {
state = {
data: [
{
id: 1,
name: "Foo",
age: "20"
},
{
id: 2,
name: "Bar",
age: "30"
},
{
id: 3,
name: "Baz",
age: "40"
}
]
};
handleNameUpdate = (id, name) => {
const { data } = this.state;
const newData = data.map(row => {
if (row.id === id) {
return {
...row,
name
};
}
return row;
});
this.setState({ data: newData });
}
render() {
return (
<div className="App">
<div className="table-responsive">
<table className="table table-hover">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Age</th>
<th>Updated Name</th>
</tr>
</thead>
<tbody>
{this.state.data.map(row => (
<TableRow
key={row.id}
data={row}
onNameUpdate={this.handleNameUpdate}
/>
))}
</tbody>
</table>
</div>
</div>
);
}
}
class TableRow extends Component {
handleChange = e => {
this.props.onNameUpdate(this.props.data.id, e.target.value);
};
render() {
const {
data: { id, name, age }
} = this.props;
return (
<tr>
<td>{id}</td>
<td>{name}</td>
<td>{age}</td>
<td>
<input type="text" value={name} onChange={this.handleChange} />
</td>
</tr>
);
}
}
export default App;
希望对您有所帮助!祝你好运!