在React中使用条件渲染处理编辑

时间:2019-12-02 01:34:20

标签: reactjs axios react-hooks

我试图有条件地渲染按钮和带有react的编辑表单。我的代码背后的想法是,单击“编辑”按钮后,“编辑”和“删除”按钮将更改为“保存并取消”,并且最初由get方法填充的h5(标题)字段更改为具有原始默认值的textareas。我以为这可能是一个不错的方法,但我犯了个严重错误。

const Users = () => {
    const [users, setUsers] = useState({ list: [] });
    const [edit, setEdit] = useState(false);

    useEffect(() => {
        axios
            .get('/api/User')
            .then(response => {
                setUsers({list:response.data});
            })
            .catch(error => {
                console.log(error);
            })
    }, []);

    const handleDelete = (user) => {

        axios
            .delete(`/api/User/${user.id}`)
            .then(response => {
                console.log(response)
                 window.location.reload(true);
             })
             .catch(error => {
                 console.log(error)
             })
    }

    const handleEdit = (user) => {       
        setEdit(true);
        return (
        <div className="section" key={user.id}>
            <div className="divider"></div>
                <textarea type="username" className="edit-userName" defaultValue={user.username}></textarea>
                <textarea type="email" className="edit-userName" defaultValue={user.email}></textarea>
                <Button className="btn-save" color="info" onClick={() => handleSave(user)}>Save</Button>
                <Button className="btn-cancel" color="info" onClick={() => setEdit(false)}>Cancel</Button>
        </div>
        )
    }

    const handleSave = (user) => {
        axios
            .put(`/api/User/${user.id}`)
            .then(response => {
                console.log(response)
            })
            .catch(error => {
                console.log(error)
            })

        setEdit(false);
    }

     return(
         <div className="container white">
             <h3 className="center"> 
             Manage Users
             <Button className="btn-createUser" color="info">
                 <Link to='/signup'>New User</Link>
             </Button>
             </h3>        
                 {users.list.map(user => (
                     <div className="section" key={user.id}>
                     <div className="divider"></div>
                         <h5 type='username' className="user-userName">{user.username}</h5>
                         <h5 type='email' className="user-userEmail">{user.email}</h5>
                         <Button className="btn-edit" color="info" onClick={() => handleEdit(user)}>Edit</Button>
                         <Button className="btn-delete" color="info" onClick={() => handleDelete(user)}>Delete</Button>
                     </div>
                 ))}
         </div>
     );
 }

 export default Users;

跟进:我得到了渲染器,将标头更改为textareas,并且放置位置现在正确地到达了端点,但是渲染器将打开所有字段,而不仅仅是打开我按下编辑的字段。

{users.list.map(user => (
                     <div className="section" key={user.id}>
                     <div className="divider"></div>
                         <h5 type='username' className="user-userName">{user.username}</h5>
                         <h5 type='email' className="user-userEmail">{user.email}</h5>
                         {edit ? (
                         <>
                         <textarea type="username" className="edit-userName" defaultValue={user.username}></textarea>
                         <textarea type="email" className="edit-userName" defaultValue={user.email}></textarea>
                         <Button className="btn-save" color="info" onClick={() => handleSave(user)}>Save</Button>
                         <Button className="btn-cancel" color="info" onClick={() => setEdit(false)}>Cancel</Button>
                         </>
                         ) : (
                        <>
                         <Button className="btn-edit" color="info" onClick={() => handleEdit(user.id)}>Edit</Button>
                         <Button className="btn-delete" color="info" onClick={() => handleDelete(user.id)}>Delete</Button>
                        </>
                        )}
                     </div>
                 ))}
         </div>

1 个答案:

答案 0 :(得分:1)

签出conditional rendering文档。我猜你有,但是你只是没有正确地实现它。

您可以在单击“编辑”时设置一个状态,就像您正在做的那样。然后,您可以使用文档中的Inline If with Logical && Operator方法为每个选项提供两行代码,并且只渲染一个按钮。对于您的其中一个按钮(而不是divider),它会以类名<Button ...>Save</Button>进入div中的.jsx:

{!edit && <Button ...>Save</Button>}
{edit && <Button ...>Edit</Button>}

或更简单地说:

{edit ? (<Button ...>Edit</Button>) : (<Button ...>Save</Button>)}

您还可以使用我链接的文档中的第一个示例,该示例使另一个组件看起来像这样(在您的Users功能组件之外!):

// Put all your logic here to figure out what to render
function SaveButton(props) {
  if (props.edit) {
    return <Button ...>Edit</Button>;
  } else {
    return <Button ...>Save</Button>;
  }
}

然后在您的功能组件中:

<SaveButton edit={edit} />

希望这可以帮助您了解如何有条件地进行渲染。

编辑为您的编辑内容

要使其仅适用于一个用户,您的编辑状态将需要更加具体。您可以使其成为数组或对象。例如:

const [edit, setEdit] = useState({}); // No one is being edited

然后,当单击编辑时,您可以通过{:{1}}

将key:value对设置为true。

这将使其充满setEdit({...edit, [user.id]: true})(正在编辑两个用户ID)。传播运算符{55: true, 68: true}是这样,因此您不会丢失任何其他正在编辑的ID。

要还原(编辑完成)时,请删除该属性或将其设置为false。

现在,在您决定呈现HTML的行中:

...edit

将其更改为:

`{edit ? (` 

这将使每个映射资源检查编辑状态对象是否具有等于其ID的true属性。