从嵌套的JSON对象中获取数据在React中

huangapple go评论77阅读模式
英文:

Getting data from nested JSON objects in React

问题

以下是您要翻译的内容:

我正在制作一个能够搜索和显示电影内容的网页应用程序,并尝试访问外部对象,比如从相同终点获取的嵌套对象“principals”。

从fetch获取的JSON响应:

{
  "title": "The Match Factory Girl",
  "year": 1990,
  "runtime": 69,
  "genres": [
    "Comedy",
    "Crime",
    "Drama"
  ],
  "country": "Finland, Sweden",
  "principals": [
    {
      "id": "nm0653669",
      "category": "actress",
      "name": "Kati Outinen",
      "characters": [
        "Iris Rukka"
      ]
    },
    {
      "id": "nm0758825",
      "category": "actress",
      "name": "Elina Salo",
      "characters": [
        "Mother"
      ]
    }
  ],
  "ratings": [
    {
      "source": "Internet Movie Database",
      "value": 7.5
    },
    {
      "source": "Rotten Tomatoes",
      "value": null
    },
    {
      "source": "Metacritic",
      "value": null
    }
  ],
  "boxoffice": 0,
  "poster": "https://m.media-amazon.com/images/M/MV5BMmM1ZTZhNDUtYzBkNi00YzQ0LWEyZjItM2M5OTI2ZTU0MDlkXkEyXkFqcGdeQXVyMjI0MjMwMzQ@._V1_SX300.jpg",
  "plot": "A woman's terribly dull life is upended by a one-night stand pregnancy, causing her to seek retribution."
}

我的目标是将“principals”中的对象渲染到AG网格上,同时显示未嵌套的对象,如“title”,“year”和“runtime”等,显示在

标签上。

我已经成功使用useEffect()将“principals”显示在AG网格上,但在尝试显示“title”方面遇到了困难。

英文:

I am making a web application that can search and display movie content and I am trying to get access to outer objects such as "title" with nested objects like "principals" - fetched from the same endpoint.

JSON response from fetch:

{
  "title": "The Match Factory Girl",
  "year": 1990,
  "runtime": 69,
  "genres": [
    "Comedy",
    "Crime",
    "Drama"
  ],
  "country": "Finland, Sweden",
  "principals": [
    {
      "id": "nm0653669",
      "category": "actress",
      "name": "Kati Outinen",
      "characters": [
        "Iris Rukka"
      ]
    },
    {
      "id": "nm0758825",
      "category": "actress",
      "name": "Elina Salo",
      "characters": [
        "Mother"
      ]
    }
  ],
  "ratings": [
    {
      "source": "Internet Movie Database",
      "value": 7.5
    },
    {
      "source": "Rotten Tomatoes",
      "value": null
    },
    {
      "source": "Metacritic",
      "value": null
    }
  ],
  "boxoffice": 0,
  "poster": "https://m.media-amazon.com/images/M/MV5BMmM1ZTZhNDUtYzBkNi00YzQ0LWEyZjItM2M5OTI2ZTU0MDlkXkEyXkFqcGdeQXVyMjI0MjMwMzQ@._V1_SX300.jpg",
  "plot": "A woman's terribly dull life is upended by a one-night stand pregnancy, causing her to seek retribution."
}

My goal is to get the objects in "principles" to render on an AG grid, meanwhile having objects that aren't nested such as "title", "year", "runtime' etc. to display on <h1> tags.

I have managed to get "principals" to show using useEffect() on an AG grid but I am lost in trying to also get "title" to display.

const [rowData, setRowData] = useState([]);
const columns = [
    {headerName: &quot;Role&quot;, field: &quot;role&quot;, sortable: true},
    {headerName: &quot;Name&quot;, field: &quot;name&quot;},
    {headerName: &quot;Characters&quot;, field: &quot;characters&quot;},
  ];


useEffect(() =&gt; {
    fetch(`${API_URL}/movies/data/${imdbID}`)
    .then(res =&gt; res.json())
    .then(people =&gt; people.principals)
    .then(principals =&gt; 
      principals.map(person =&gt; {
        return {
          role: person.category,
          name: person.name,
          characters: person.characters,
          id: person.id
        }
    }))
    .then(allPeople =&gt; setRowData(allPeople))
    .then(test =&gt; console.log(&quot;ss&quot;))
    .catch(error =&gt; console.log(error))
  }, []);


return (
    &lt;div&gt;
        &lt;h1&gt; The title of the movie is... &lt;/h1&gt;
        &lt;div className=&quot;ag-theme-balham&quot; style={{height: &quot;300px&quot;, width: &quot;1100px&quot;}}&gt;
          &lt;AgGridReact columnDefs={columns}  rowData={rowData} pagination={true} paginationPageSize={7}/&gt;
        &lt;/div&gt;
    &lt;/div&gt;
  )

答案1

得分: 1

将整个电影对象存储在状态中。在组件的主体中获取yeartitle并创建rows

你可以将rows的映射用useMemo包装起来,以避免在每次渲染时都进行映射,当movie不发生变化时:

const [movie, setMovie] = useState(null);

const { title, year, principals } = movie;

useEffect(() => {
  fetch(`${API_URL}/movies/data/${imdbID}`)
  .then(res => res.json())
  .then(setMovie) // 将电影存储在状态中
  .catch(error => console.log(error))
}, []);

const rows = useMemo(() => principals.map(person => ({
  role: person.category,
  name: person.name,
  characters: person.characters,
  id: person.id
})), [movie])

return (
  <div>
    <h1> 电影的标题是 {title} / {year}</h1>
    <div className="ag-theme-balham" style={{height: "300px", width: "1100px"}}>
      <AgGridReact columnDefs={columns}  rowData={rowData} pagination={true} paginationPageSize={7}/>
    </div>
  </div>
);
英文:

Store the entire movie object in the state. Get the year, title and create the rows in the body of the component.

You can wrap the rows mapping with useMemo to avoid mapping it on each render, when movie doesn't change:

const [movie, setMovie] = useState(null);

const { title, year, principals } = movie;

useEffect(() =&gt; {
  fetch(`${API_URL}/movies/data/${imdbID}`)
  .then(res =&gt; res.json())
  .then(setMovie) // store movie in the state
  .catch(error =&gt; console.log(error))
}, []);

const rows = useMemo(() =&gt; principals.map(person =&gt; ({
  role: person.category,
  name: person.name,
  characters: person.characters,
  id: person.id
})), [movie])

return (
  &lt;div&gt;
    &lt;h1&gt; The title of the movie is {title} / {year}&lt;/h1&gt;
    &lt;div className=&quot;ag-theme-balham&quot; style={{height: &quot;300px&quot;, width: &quot;1100px&quot;}}&gt;
      &lt;AgGridReact columnDefs={columns}  rowData={rowData} pagination={true} paginationPageSize={7}/&gt;
    &lt;/div&gt;
  &lt;/div&gt;
);

答案2

得分: 1

这是您的代码的翻译部分:

It's simple.. You're only returning principles from your api response. You need to return the whole object with the formatted principles, as follows

const [rowData, setRowData] = useState([]);
const [data, setData] = useState({});
useEffect(() => {
  fetch(`${API_URL}/movies/data/${imdbID}`)
    .then((res) => res.json())
    .then((people) => people)
    .then((people) => {
      return {
        ...people,
        principles: people.principals.map((person) => ({
          role: person.category,
          name: person.name,
          characters: person.characters,
          id: person.id,
        })),
      };
    })
    .then((allPeople) => {
      setData(allPeople);
      setRowData(allPeople.principals);
    })
    .then((test) => console.log('ss'))
    .catch((error) => console.log(error));
}, []);

return (
  <div>
    <h1> The title of the movie is: {data.title} </h1>
    <div
      className="ag-theme-balham"
      style={{ height: '300px', width: '1100px' }}
    >
      <AgGridReact
        columnDefs={columns}
        rowData={rowData}
        pagination={true}
        paginationPageSize={7}
      />
    </div>
  </div>
);

请注意,我只翻译了您提供的代码部分,不包括其他内容。

英文:

It's simple.. You're only returning principles from your api response. You need to return the whole object with the formatted principles, as follows

const [rowData, setRowData] = useState([]);
const [data, setData] = useState({});
useEffect(() =&gt; {
fetch(`${API_URL}/movies/data/${imdbID}`)
.then((res) =&gt; res.json())
.then((people) =&gt; people)
.then((people) =&gt; {
return {
...people,
principles: people.principals.map((person) =&gt; ({
role: person.category,
name: person.name,
characters: person.characters,
id: person.id,
})),
};
})
.then((allPeople) =&gt; {
setData(allPeople);
setRowData(allPeople.principals);
})
.then((test) =&gt; console.log(&#39;ss&#39;))
.catch((error) =&gt; console.log(error));
}, []);
return (
&lt;div&gt;
&lt;h1&gt; The title of the movie is: {data.title} &lt;/h1&gt;
&lt;div
className=&quot;ag-theme-balham&quot;
style={{ height: &#39;300px&#39;, width: &#39;1100px&#39; }}
&gt;
&lt;AgGridReact
columnDefs={columns}
rowData={rowData}
pagination={true}
paginationPageSize={7}
/&gt;
&lt;/div&gt;
&lt;/div&gt;
);

huangapple
  • 本文由 发表于 2023年5月7日 18:46:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76193439.html
  • javascript
  • json
  • react-hooks
  • reactjs