简体   繁体   English

使用 useState 反应挂钩更新对象数组

[英]Updating array of objects with useState react hook

I'm working on a simple project using react hooks, I want to update the state from fetched data from the api http://geoplugin.net/json.gp .我正在使用反应挂钩进行一个简单的项目,我想从 api http://geoplugin.net/json.gp 获取的数据更新 state However, when I try to update the state it's not working.但是,当我尝试更新 state 时,它不起作用。 Only the initial state is returned.只返回初始的 state。

 import React, { Fragment,useState,useEffect } from 'react';
 import {container,Row,Table} from 'reactstrap';
 import axios from 'axios';

function LiveVisitors() {
 const [visitors,setVisitors] =useState([{
     ip: '',
             countryCode: '',
             city: '',
             state: '',
             country: ''
 }]);
const {ip,countryCode,city,state,country} = visitors;

 useEffect(()=>{
     getUserData()
 },[])
 //get user data
 const getUserData = () =>{

 const  res=  axios.get(`http://geoplugin.net/json.gp`).then(res =>{
    // console.log(res)
     const {geoplugin_request,
                     geoplugin_countryCode,
                     geoplugin_countryName,
                     geoplugin_city,
                     geoplugin_region
     
                 } =res.data;
     const visitor = {
         ip: geoplugin_request,
         countryCode: geoplugin_countryCode,
         city: geoplugin_city,
         state: geoplugin_region,
         country: geoplugin_countryName
                 };
     setVisitors(visitors => [...visitors,visitor])
     console.log(res.data)
     console.log({visitor})
     console.log(visitors)
 }).catch (err =>{
     console.log(err)
 })  
     
 }

Your code works when you remove the axios part that is breaking the setState.当您删除破坏 setState 的 axios 部分时,您的代码有效。 I prepared an example for you that works and adds another visitor element.我为您准备了一个有效的示例,并添加了另一个访问者元素。

https://codesandbox.io/s/react-playground-forked-hqswi?file=/index.js https://codesandbox.io/s/react-playground-forked-hqswi?file=/index.js

import React, { Fragment, useState, useEffect } from "react";
import ReactDOM from "react-dom";

function LiveVisitors() {
  const [visitors, setVisitors] = useState([
    {
      ip: "",
      countryCode: "",
      city: "Warsaw",
      state: "",
      country: "Poland"
    },
    {
      ip: "",
      countryCode: "",
      city: "Gdańsk",
      state: "",
      country: "Poland"
    }
  ]);
  const { ip, countryCode, city, state, country } = visitors;

  useEffect(() => {
    getUserData();
  }, []);

  const getUserData = () => {
    //imitate fetch
    setVisitors([
      ...visitors,
      {
    ip: "",
    countryCode: "",
    city: "Wrocław",
    state: "",
    country: "Poland"
      }
    ]);
  };

  return (
    <div>
      {visitors.map((el) => (
    <div>{el.city}</div>
      ))}
    </div>
  );
}

const wrapper = document.getElementById("container");
ReactDOM.render(<LiveVisitors />, wrapper);

By using useEffect with an empty array at the end you force it to run only once通过在末尾使用带有空数组的useEffect强制它只运行一次

Try尝试

useEffect(()=>{
     getUserData()
},[visitors]);

or without the array或者没有数组

useEffect(()=>{
     getUserData()
});

it should trigger every time React detects a change, hope that helps.它应该在每次 React 检测到变化时触发,希望能有所帮助。

Here is a really good article that gives a good explanation.这是一篇非常好的文章,给出了很好的解释。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM