Javascript 基于ID在React中编辑对象数组中的属性

Javascript 基于ID在React中编辑对象数组中的属性,javascript,arrays,reactjs,object,2d-context-api,Javascript,Arrays,Reactjs,Object,2d Context Api,我在新的“上下文API”中创建了一个对象数组,如下所示 const reducer = (state, action) => { switch (action.type) { case "DELETE_CONTACT": return { ...state, contacts: state.contacts.filter(contact => {

我在新的“上下文API”中创建了一个对象数组,如下所示

const reducer = (state, action) => {
    switch (action.type) {
        case "DELETE_CONTACT":
            return {
                ...state,
                contacts: state.contacts.filter(contact => {
                    return contact.id !== action.payload;
                })
            };
        default:
            return state;
    }
};

export class Provider extends Component {
    state = {
        contacts: [
            {
                id: 1,
                name: "John Doe",
                email: "jhon.doe@site.com",
                phone: "01027007024",
                show: false
            },
            {
                id: 2,
                name: "Adam Smith",
                email: "adam.smith@site.com",
                phone: "01027007024",
                show: false
            },
            {
                id: 3,
                name: "Mohammed Salah",
                email: "mohammed.salah@site.com",
                phone: "01027007024",
                show: false
            }
        ],
        dispatch: action => {
            this.setState(state => reducer(state, action));
        }
    };

    render() {
        return (
            <Context.Provider value={this.state}>
                {this.props.children}
            </Context.Provider>
        );
    }
}
const reducer=(状态、操作)=>{
开关(动作类型){
案例“删除联系人”:
返回{
……国家,
联系人:state.contacts.filter(联系人=>{
return contact.id!==action.payload;
})
};
违约:
返回状态;
}
};
导出类提供程序扩展组件{
状态={
联系人:[
{
id:1,
姓名:“约翰·多伊”,
电子邮件:“约翰。doe@site.com",
电话:01027007024,
节目:假
},
{
id:2,
名称:“亚当·斯密”,
电子邮件:“亚当。smith@site.com",
电话:01027007024,
节目:假
},
{
id:3,
姓名:“穆罕默德·萨拉赫”,
电子邮件:“穆罕默德。salah@site.com",
电话:01027007024,
节目:假
}
],
调度:操作=>{
this.setState(state=>reducer(state,action));
}
};
render(){
返回(
{this.props.children}
);
}
}

我想在“reducer”中创建一个操作,允许我根据每个联系人的id编辑其“show”属性,我将该id作为有效负载传递给该操作,如何才能做到这一点?

您可以找到联系人,使用
spread
避免突变,设置
show
的新值:

case "EDIT_CONTACT":
    const { id, show } = action.payload; // Assume id and show are in action.payload
    const contact = { ...state.contacts.find(c => c.id === id), show };
    return {
        ...state,
        contacts: [...state.contacts.filter(c => c.id !== id), contact]
    };
如果订单重要:

    const { id, show } = action.payload; 
    const contact = { ...state.contacts.find(c => c.id === id), show };
    const index = state.contacts.findIndex(c => c.id === id);
    return {
            ...state,
            contacts = [ ...state.contacts.slice(0, index), contact, ...state.contacts.slice(index + 1)];
    }

要避免阵列突变并在编辑联系人时保留元素位置,可以执行以下操作:

case "EDIT_CONTACT":
    const { id, show } = action.payload;
    const contact = { ...state.contacts.find(c => c.id === id), show };
    return {
       ...state,
       contacts: state.contacts.map(c => {return (c.id !== id) ? c : contact;})        
    };

好吧,这是可行的,但在编辑属性之后,它会将编辑过的对象推到数组的底部。如果我像这样点它<代码>联系人:[contact,…state.contacts.filter(c=>c.id!==id)]它将它放在数组的顶部。感谢这个解决方案,它可以工作,但我认为@samee solution看起来更优雅。