ar-coding
ar-coding

Reputation: 461

Render react component from jsx fetch result

I am trying to render fetched data, which is an array of JSX to be rendered.

return(dataList.map((data) => (
                <CustomComponent1>
                    <CustomComponent2>{data.name}</CustomComponent2> 
                </CustomComponent1>
      )));

I get result like

[
    {
        "key": null,
        "ref": null,
        "props": {
            "children": [
                {
                    "key": null,
                    "ref": null,
                    "props": {
                        "textAlign": "left",
                        "verticalAlign": "top"
                    },
                    "_owner": null,
                    "_store": {}
                },
                
......

First of all, I don't see children getting updated with the value passed. How can I give a unique key to each entry? How do I render this as react element on the parent component?

Upvotes: 0

Views: 42

Answers (1)

Nick Vu
Nick Vu

Reputation: 15540

How can I give a unique key to each entry?

You should add key prop to child elements in iteration. That will help you to identify elements in multiple similar elements.

Note that id will be more suitable in this case but I'm using item.name as a key because I don't know if your data has id or not.

I don't see children getting updated with the value passed

Your above logic seems correct, but possibly your problem is from state updates. Due to the nature of React's immutability rule, you cannot mutate a state but create a new object mapping with the state.

const mockedDataList = [{ name: "name 1" }, { name: "name 2" }, { name: "name 3" }]

const ChildComponent = ({ children }) => {
   return children
}

const ParentComponent = () => {
   const [dataList,setDataList] = React.useState(mockedDataList)
   const mappedElements = dataList.map((data) => <ChildComponent key={data.name}>{data.name}</ChildComponent>);
   const handleClick = () => {
      //cannot do this
      //dataList[1] = "name 4"
      //setDataList(dataList)
      //-----------
      //should do this instead
      const updatedDataList = dataList.map(data => data.name === "name 2" ? {...data, name: "name 4"} : data)
      setDataList(updatedDataList)
   }
   console.log(mappedElements);
   return <div>
   {mappedElements}
   <button onClick={handleClick}>Change name 2 to name 4</button>
   </div>
}

ReactDOM.render(
  <ParentComponent/>,
  document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Upvotes: 1

Related Questions