首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用CodeMirror 6编辑器错误地更新嵌套组件中的状态

用CodeMirror 6编辑器错误地更新嵌套组件中的状态
EN

Stack Overflow用户
提问于 2021-07-26 20:41:19
回答 2查看 208关注 0票数 0

我有几个组件嵌套在一个更大的“控制器”组件中。

整个演示应用程序如下。还有一个StackBlitz

代码语言:javascript
运行
复制
import React, { useState } from 'react';
import CodeEditor from './CodeEditor';
import './style.css';

const PostEditor = ({ value, onChange }) => {
  return (
    <>
      {value && (
        <>
          <CodeEditor value={value} onChange={value => onChange(value)} />
        </>
      )}
    </>
  );
};

const Wrapper = ({ post, updatePostProperty }) => {
  return (
    <>
      <h2>Selected post: {post && post.title}</h2>
      {post && post.title && (
        <PostEditor
          value={post.title}
          onChange={value => {
            console.log('update title->', value);
            updatePostProperty(post.id, 'title', value);
          }}
        />
      )}
      {post && post.subTitle && (
        <PostEditor
          value={post.subTitle}
          onChange={value => {
            console.log('update subTitle->', value);
            updatePostProperty(post.id, 'subTitle', value);
          }}
        />
      )}
    </>
  );
};

export default function App() {
  const [posts, setPosts] = useState([
    { id: 1, title: 'post no 1', subTitle: 'subtitle no 1' },
    { id: 2, title: 'post no 2', subTitle: 'subtitle no 2' },
    { id: 3, title: 'post no 3', subTitle: 'subtitle no 3' }
  ]);
  const [post, setPost] = useState();

  const updatePostProperty = (id, property, value) => {
    const newPosts = [...posts];
    const index = newPosts.findIndex(post => (post.id === id));
    newPosts[index] = {
      ...newPosts[index],
      [property]: value
    };
    setPosts(newPosts);
  };
  return (
    <div>
      <ul>
        {posts &&
          posts.length > 0 &&
          posts.map((post, index) => (
            <li
              style={{ cursor: 'pointer' }}
              onClick={() => {
                setPost(post);
              }}
            >
              {post.title} - {post.subTitle}
            </li>
          ))}
      </ul>

      <Wrapper post={post} updatePostProperty={updatePostProperty} />
    </div>
  );
}

App组件承载传递给Wrapper组件的updatePostProperty,该组件在PostEditor组件触发CodeEditor时使用它,CodeEditorCodeMirror的包装器。

这里的问题是,在单击其中一个帖子并编辑标题,然后编辑副标题后,标题将被恢复为初始值。

设想情况:

点击第一个帖子并尝试编辑标题。在标题中添加一个!。你会看到列表上的帖子被更新了。

在通过向字幕中添加字符来编辑字幕之后,您将看到App组件中的标题被恢复到以前的状态(没有App)。

为什么要做这个“还原”更新?

更新

新StackBlitz

  • 在更改原始的useEffect数组之前,我对脚本做了一些调整,以使用posts
  • 我添加了一个常规的input元素来查看问题是否仍然存在。这个问题似乎是用常规的input来解决的。

不过,我希望有人能给我介绍一下,为什么这个问题仍然存在于CodeMirror的连接方式上。

EN

回答 2

Stack Overflow用户

发布于 2021-07-26 20:55:11

updatePostProperty内部,您正在更新错误的对象。

你在更新:

代码语言:javascript
运行
复制
posts[index] = {
  ...newPosts[index],
  [property]: value
};

但是您想要更新newPosts,所以您必须这样做:

代码语言:javascript
运行
复制
newPosts[index] = {
  ...newPosts[index],
  [property]: value
};
票数 1
EN

Stack Overflow用户

发布于 2021-07-26 21:15:17

  1. 它需要是newPosts而不是posts
  2. 不需要破坏
  3. 这里使用的是1 =newPosts.findIndex(post => (post.id = id));,假设有2 ==,类似于newPosts.findIndex(post => (post.id == id));

签出这段代码

代码语言:javascript
运行
复制
  const updatePostProperty = (id, property, value) => {
    const newPosts = [...posts]; 
    const index = newPosts.findIndex(post => (post.id == id)); 
    newPosts[index][property] = value
    setPosts(newPosts);
  };
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68536101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档