我正在尝试创建更新应用程序状态的输入行。该应用程序目前只有两个组件,TimeCalc和ItemsList。 State存储在TimeCalc中,ItemsList处理条件渲染(显示状态或显示输入行。
我已设法获取已编辑和更新的对象,但我正在努力用正确的状态对象替换更新的对象。对象包含道具_id,title,start和end,最好是我想搜索匹配的_id,并替换状态中的整个对象。但是看到_id道具是其他道具的兄弟支柱,我不知道该怎么做。
这是TimeCalc:
import React from 'react';
import ItemsList from '../components/ItemsList';
const items = [
{
_id: '112233',
title: 'M1',
start: 900,
end: 1800
},
{
_id: '223344',
title: 'M2',
start: 1000,
end: 1900
}
];
export default class TimeCalc extends React.Component {
state = {
items
}
handleUpdate = (update) => {
}
render = () => {
return (
<div class="timeCalc flex center">
<ItemsList items={this.state.items} handleUpdate={this.handleUpdate}/>
</div>
)
}
}
这是ItemsList:
import React from 'react';
export default class ItemsList extends React.Component {
state = {
editing: null
}
toggleEditing = (itemId) => {
this.setState({
editing: itemId
})
}
handleEditItem = () => {
let itemId = this.state.editing;
this.handleItemsUpdate({
_id: itemId,
title: this.refs[`title_${itemId}`].value,
start: this.refs[`start_${itemId}`].value,
end: this.refs[`end_${itemId}`].value,
})
}
handleItemsUpdate = (update) => {
console.log(update);
this.props.handleUpdate(update);
this.setState( { editing: null } );
}
renderItemOrEditField = (item) => {
if(this.state.editing === item._id) {
return <li key={`editing-${item._id} `} class="list-item flex row">
<input
onKeyDown={this.handleEditField}
type="text"
class="form-input"
ref={`title_${item._id}`}
name="title"
defaultValue={item.title}
/>
<input
onKeyDown={this.handleEditField}
type="text"
class="form-input"
ref={`start_${item._id}`}
name="start"
defaultValue={item.start}
/>
<input
onKeyDown={this.handleEditField}
type="text"
class="form-input"
ref={`end_${item._id}`}
name="end"
defaultValue={item.end}
/>
<button onClick={this.handleEditItem} label="Update Item"/>
</li>
} else {
return <li
onClick = {this.toggleEditing.bind(null, item._id)}
key = {item._id}
class = "list-position">
{` ${item.title} & ${item.start} && ${item.end} && ${item._id}`}
</li>
}
}
render = () => {
return (
<ul class="itemsList">
{this.props.items.map((item) => {
return this.renderItemOrEditField(item);
})}
</ul>
)
}
}
我试图在React&#34;中重新创建MeteorChef&#34;点击编辑字段,但他以流星方式存储状态。
答案 0 :(得分:0)
我建议您将所有状态移动到父组件。保持ItemsList无状态可以更清晰地区分您的问题并使代码更容易理解。在这种情况下,需要关注的所有ItemsList都是根据存储在父级中的状态来呈现数据。在TimeCalc组件中,向状态对象添加“编辑”键,并添加一个方法来处理ItemsList中的更新:
state = {
items,
editing: null,
}
handleUpdate = (editing) => {
this.setState({ editing });
}
然后在渲染子组件时,将此处理函数,items数组和“编辑”键作为props传递:
<ItemsList items={this.state.items} editing={this.state.editing} handleUpdate={this.handleUpdate}/>
现在,ItemsList可以成为无状态功能组件,如下所示:
import React from 'react';
const renderItemOrEditField = (item, editing, handleUpdate) => (
{editing === item._id ? (
<li key={item._id} className="list-item flex row">
<input onKeyDown={handleUpdate(item._id}
// The rest of your content to render if item is being edited
) : (
// content to be rendered if item isn't being edited goes here
)}
);
export default const ItemsList = (props) => (
<ul className="itemsList">
{props.items.map((item) => {
return renderItemOrEditField(item, props.editing, props.handleUpdate);
})}
</ul>
);
这种使用“智能”容器组件管理状态和业务逻辑以及“哑”表示组件的策略可以大大有助于保持应用程序的可维护性和脆弱性。希望这有帮助!