reactjs 输入的状态值应该在子组件还是父组件中?

nlejzf6q  于 2023-03-22  发布在  React
关注(0)|答案(2)|浏览(171)

假设我有一个名为Profile的个人资料页面的父组件和一个名为Post的子组件,我想介绍一个功能,如果用户选择,它可以更新帖子的内容。
我理解为什么把我正在编辑的文章的ID放在父组件中比放在子组件Post中更好,因为我想一次只允许编辑一个文章。存储我正在编辑的文章的ID允许我一次只编辑一个文章,即处于状态的文章。
然而,我不确定从这里开始使用React的最佳实践,特别是与newContent我想成为正在编辑的帖子的新内容。
用户输入的<input/>内容是否应该存储在父组件或子组件中的某个状态中?
例如,如果我将[newContent, setNewContent]存储在父组件中,我将不得不将setNewContent状态更新器发送给子组件,并使用e.target.value更新状态。如果我将其存储在子组件中,我将在传递给Post组件的onEdit()函数中发送newContent的当前状态,但是在修改完成后,在哪里或如何设置newContent(null)变得令人困惑。在用户单击submitEdit按钮后,应该将其设置为null吗?在提交请求后,在updatePostContent函数中?(这也变得令人困惑)

export default function Profile() {
  const [posts, setPosts] = useState([]);
  const [editingPostId, setEditingPostId] = useState(null);

  const updatePostContent = async (id, newContent) => {
    // HTTP put request to update post, and then updates the posts state with updatedPost
  };

  return (
    <div>
      <h1>Profile Page</h1>

      <p>posts: </p>
      {posts.map((post) => (
        <Post
          key={post.id}
          post={post}
          isEditing={editingPostId === post.id}
          onEdit={(newContent) => {
            updatePostContent(post.id, newContent);
          }}
          cancelEdit={() => setEditingPostId(null)}
        />
      ))}
    </div>
  );
}

export function Post({ post, isEditing, onEdit }) {
  return (
    <div>
      <h1>{post.id}</h1>
      <p>{post.content}</p>

      {/* if is editing */}
      {isEditing && (
        <>
          <input type="text" onChange={(e) => console.log(e.target.value)} />
          <button onClick={() => onEdit(newContent)}>submit edit</button>
          <button onClick={cancelEdit}>cancel editing</button>
        </>
      )}
    </div>
  );
}

我的直觉告诉我没有必要在child中存储newContent状态,因为一次只能编辑一个post,没有必要让child组件存储输入的任何内容,因为这将意味着多个子组件将在其内部具有未使用状态,而实际上并不需要它,因为一次仅编辑一个帖子。
你们推荐什么?

gcuhipw9

gcuhipw91#

这是我的观点:
TLDR;每个组件都应该知道它的内容/值。这就是React中状态的目的。因此,子组件应该拥有newContent的所有权。一旦提交了值,该值应该返回到父组件,并在'显示内容'或'编辑帖子'的情况下将其提供给子组件。
现在,到描述部分:在这种情况下,Post组件应该知道与它相关联的用户输入,以防它需要对用户输入值执行某些操作。一旦提交,该值应该通过回调与帖子的标识符沿着传递回Profile组件。然后回调方法将根据相应的标识符存储提交的内容。在回调之前,您可以清除Post组件上的输入字段。
在“列出帖子内容”或“编辑帖子”场景的情况下,内容将作为prop传递给Post组件。
注意:您也可以考虑跳过在Post组件的状态中存储newContent值,直接将输入值传递给回调。
希望这个有用。

ubbxdtey

ubbxdtey2#

我是这样看的:

备选案文1

如果原始状态(包含posts的数组)在父级中,我会更新父级中的状态,并将updatePostContent作为prop传递给您的组件,其中您有更新“form”。

const Parent = () => {
  const [posts, setPosts] = useState([]);
  const updatePostContent = async (id, content) => {
    // your logic here
  } 
  return (
    <div>
      <h1>Profile Page</h1>

      <p>posts: </p>
      {posts.map((post) => (
        <Post
          key={post.id}
          post={post}
          updatePost={updatePostContent}
        />
      ))}
    </div>
  );
}

const Post = ({ post, isEditing, updatePost }) => {
  const inputRef = useRef(null);

  const submitChagne = () => {
    // handle validation first, for example
    updatePost(post.id, inputRef.current.value);
  }
  return (
    <div>
      <h1>{post.id}</h1>
      <p>{post.content}</p>

      {/* if is editing */}
      {isEditing && (
        <>
          <input type="text" ref={inputRef} />
          <button onClick={submitChange}>submit edit</button>
          <button onClick={cancelEdit}>cancel editing</button>
        </>
      )}
    </div>
  );
}

一般来说,我不鼓励 prop 钻孔(通过多个组件广泛使用 prop ),但如果它只是一个直接的父,我不明白为什么不。

备选案文2

如果你必须通过很多组件(prop drilling),我建议使用一个useContext钩子。
下面是一个SO答案,它稍微解释了上下文钩子:React - useContext

相关问题