【问题标题】:Handling Edit with Conditional Rendering in React在 React 中使用条件渲染处理编辑
【发布时间】:2019-12-02 01:34:20
【问题描述】:

我试图通过反应有条件地呈现按钮和编辑表单。我的代码背后的想法是,单击编辑按钮后,编辑和删除按钮会更改为保存和取消,并且最初由 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 并且 put 现在正确命中端点,但是渲染将打开所有字段,而不是简单地打开我按下编辑的那个。

{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>

【问题讨论】:

    标签: reactjs axios react-hooks


    【解决方案1】:

    查看conditional rendering 文档。我猜你有,但你只是没有完全正确地实施它。

    您可以在单击编辑时设置一个状态,看起来就像您正在做的那样。然后,您可以为每个选项使用两行代码,使用文档中的 Inline If with Logical &amp;&amp; Operator 方法,并且只会呈现一个按钮。这将进入 div 内的 .jsx,类名 divider 用于您的一个按钮(而不是 &lt;Button ...&gt;Save&lt;/Button&gt;):

    {!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
    

    然后,当单击编辑时,您可以使用通过setEdit({...edit, [user.id]: true}) 解析为真值的键:值对设置编辑

    这将使它充满{55: true, 68: true}(正在编辑两个用户ID)。扩展运算符...edit 是为了让您不会丢失任何其他正在编辑的 id。

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

    现在,在您决定渲染 HTML 的行中:

    `{edit ? (` 
    

    改成:

    `{edit[user.id] ? (`
    

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

    【讨论】:

    • 感谢您的帮助!我在上面进行了一个小编辑,我正在寻求帮助以使渲染正常工作,但我需要它特定于特定用户
    • 做了一些应该有帮助的改变。
    • 我试图这样做,但现在编辑将永远不会呈现编辑。我完全理解将特定 id 设置为 true,以便您只编辑该字段
    • 尝试将您的代码发布到codesandbox.io,除此之外您必须调试为什么您的edit[user.id] 总是解析为false。学习调试是一项节省大量时间的技能。如何在代码中放置断点并查看状态和变量的状态。这是我不喜欢 in-line if 并且更喜欢做一个元素变量或另一个组件的原因之一,它更容易调试。
    猜你喜欢
    • 2021-06-07
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 2020-03-24
    • 2019-01-02
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多