I have a few components nested inside a larger "controller" component.
The whole demo app is below. There's also a StackBlitz.
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>
);
}
The App component hosts the updatePostProperty that is passed on to the Wrapper component which uses it when the PostEditor component triggers onChange the CodeEditor which is a wrapper for CodeMirror.
The issue here is that after you click one of the posts and edit the title and then the subtitle, the title gets reverted to the initial value.
Scenario:
Click on the first post and try to edit the title. Add an ! to the title. You'll see the post on the list gets updated.
After you edit the subtitle by adding a character to it, you'll see the title gets reverted to the previous state (without the !) in the App component.
Why is react doing this "revert" update?
Update:
- I made a few adjustments to the script to use
useEffectbefore changing the originalpostsarray. - I added a regular
inputelement to see if the problem persists. It seems that the issue is fixed with regularinputs.
However, I'd love someone's input on why does the issue still persists with the way CodeMirror is wired up.

newPostsinstead ofposts=herenewPosts.findIndex(post => (post.id = id));there suppose to be 2==likenewPosts.findIndex(post => (post.id == id));checkout this code