Issue
I have 2 buttons, Single Component
and Multiple Component
.
When I click on Multiple Component
, I expect it to add 3 components, but it adds only 1.
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { observer } from "mobx-react-lite";
function App() {
const [component, setComponent] = useState([]);
useEffect(() => {});
const newArray = [1, 2, 3];
const Test = observer(() => {
return (
<div>
<p>Test</p>
</div>
);
});
const Test2 = observer(() => {
return (
<div>
<p>Test2</p>
</div>
);
});
const Test3 = observer(() => {
return (
<div>
<p>Test3</p>
</div>
);
});
async function MultipleComponent() {
newArray.map(async (x) => {
if (x === 1) {
await setComponent([...component, Test]);
} else if (x === 2) {
await setComponent([...component, Test2]);
} else {
await setComponent([...component, Test3]);
}
console.log(x);
});
}
return (
<div>
{component.map((Input, index) => (
<Input components={component} key={index} />
))}
<button onClick={() => setComponent([...component, Test])}>
Single Component
</button>
<button onClick={() => MultipleComponent()}>Multiple Component</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
codensadbox: https://codesandbox.io/s/react-hooks-useeffect-forked-edmgb5
Solution
There is no point in using await
on setState
, nowhere the docs say it is a good idea.
On the other hand you need to use version of setState
which accepts an updater function, there you can get previous state.
setComponent(ps=>[...ps, Test2])
Also, I don't have link to official docs, but I am not sure storing components inside state is good idea either. You could store some identifier in state which indicates which component it is and then render that one when time comes. Here is what I mean by this:
let Test1 = (props) => {
return <div>1</div>;
};
let Test2 = (props) => {
return <div>2</div>;
};
let GeneralComponent = (props) => {
if (props.comp === '1') return <Test1 />;
if (props.comp === '2') return <Test2 />;
return null;
};
export default function App() {
let [comp, setComp] = React.useState('1');
return (
<div onClick={() => setComp(comp === '1' ? '2' : '1')}>
<GeneralComponent comp={comp} />
</div>
);
}
The GeneralComp
accepts an identifier of which component to render, which is stored in state in parent.
Answered By - Giorgi Moniava
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.