通过api调用更新对象的状态数组

时间:2020-10-23 16:01:31

标签: javascript arrays reactjs axios react-hooks

嘿,让我解释一下我的问题,我的标签状态为tag_data:

const  [tagData, setTagData] = useState([
    { key: '1', label: 'Music', active: 0 },
    { key: '2', label: 'Sport', active: 0 },
    { key: '3', label: 'Dance', active: 0 },
    { key: '4', label: 'Cook', active: 0},
    { key: '5', label: 'Video Games', active: 0},
    { key: '6', label: 'Travel', active: 0 },
    { key: '7', label: 'Picture', active: 0 },
    { key: '8', label: 'Animals', active: 0 },
    { key: '9', label: 'Coding', active: 0},
    { key: '10', label: 'Party', active: 0},
])

我进行了一个api调用,以从用户中获取ACTIVE标签:

useEffect(() => {
   const fetchData = async () => {
       setLoad(true)
       try {
           const result = await axios.post('/user/activetag')
           console.log(result.data.active_tag)
            setTagData({
                   // update
            })
       } catch (error) {
           console.log(error)
       }
       setLoad(false)
   }
   fetchData()
}, [])

然后结果存储如下活动标签:

active_tag: Array(5)
0: {tag_id: 1, label: "Music"}
1: {tag_id: 2, label: "Sport"}
2: {tag_id: 3, label: "Dance"}
3: {tag_id: 4, label: "Cook"}
4: {tag_id: 5, label: "Video Games"}

我想更新tagData状态并将active设置为1,其中tag_id等于tagData状态的键,知道吗?

完整代码:

import React, {useState, useEffect} from "react";
import { makeStyles } from '@material-ui/core/styles';
import Chip from '@material-ui/core/Chip';
import Paper from '@material-ui/core/Paper';
import DoneIcon from '@material-ui/icons/Done';
import axios from 'axios'
import Loading from '../../../../Loading/Loading'

const useStyles = makeStyles((theme) => ({
  // style
 })
export default function TagUser(){
const classes = useStyles();
const [load, setLoad] = useState(false)
const  [tagData, setTagData] = useState([
    { key: '1', label: 'Music', active: 0 },
    { key: '2', label: 'Sport', active: 0 },
    { key: '3', label: 'Dance', active: 0 },
    { key: '4', label: 'Cook', active: 0},
    { key: '5', label: 'Video Games', active: 0},
    { key: '6', label: 'Travel', active: 0 },
    { key: '7', label: 'Picture', active: 0 },
    { key: '8', label: 'Animals', active: 0 },
    { key: '9', label: 'Coding', active: 0},
    { key: '10', label: 'Party', active: 0},
])

useEffect(() => {
   const fetchData = async () => {
       setLoad(true)
       try {
           const result = await axios.post('/user/activetag')
           console.log(result.data)
           setTagData({
                   // update
            })
        } catch (error) {
           console.log(error)
       }
       setLoad(false)
   }
   fetchData()
}, [])


const handleDelete = (key) => {
    //delete
}
const handleSubmit = (key) => {
    //submit
}

if(load){
    return <Loading/>
} else {
return(
    <Paper variant="outlined" square component="span" className={classes.root}>
       {
           tagData.map((data) => {
               if (data.active === 0) {
                   return (
                       <li key={data.key}>
                           <Chip
                               variant="outlined"
                               color="secondary"
                               label={data.label}
                               className={classes.chip}
                               onDelete={() => handleSubmit(data.key)}
                               deleteIcon={<DoneIcon />} 
                           />
                       </li>
                   )
               } else {
                   return (
                       <li key={data.key}>
                           <Chip
                               color="secondary"
                               label={data.label}
                               className={classes.chip}
                               onDelete={() => handleDelete(data.key)}
                           />
                       </li>
                   )
               }
           })
       }
   </Paper>
  )
 }
}

2 个答案:

答案 0 :(得分:1)

Disclosure:我是此答案中使用的suspense-service库的作者。

如果您愿意使用第三方库,它将大大简化您的数据获取逻辑。您将不需要load状态或useEffect(),该组件仅在列表准备就绪时才会呈现:

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Chip from '@material-ui/core/Chip';
import Paper from '@material-ui/core/Paper';
import DoneIcon from '@material-ui/icons/Done';
import axios from 'axios';
import { createService, useService } from 'suspense-service';
import Loading from '../../../../Loading/Loading';

const defaultTags = [
  { key: '1', label: 'Music', active: 0 },
  { key: '2', label: 'Sport', active: 0 },
  { key: '3', label: 'Dance', active: 0 },
  { key: '4', label: 'Cook', active: 0},
  { key: '5', label: 'Video Games', active: 0},
  { key: '6', label: 'Travel', active: 0 },
  { key: '7', label: 'Picture', active: 0 },
  { key: '8', label: 'Animals', active: 0 },
  { key: '9', label: 'Coding', active: 0},
  { key: '10', label: 'Party', active: 0},
];

const UserActiveTags = createService(async (allTags) => {
  try {
    const result = await axios.post('/user/activetag');

    console.log(result.data.active_tag);

    const activeTags = result.data.active_tag.map((tag) => tag.tag_id);
    const activeTagsSet = new Set(activeTags);

    return allTags.map((tag) => ({
      ...tag,
      active: activeTagsSet.has(tag.key) ? 1 : 0
    }));
  } catch (error) {
    console.log(error);
    return allTags;
  }
});

export default function TagUser() {
  return (
    <UserActiveTags.Provider request={defaultTags} fallback={<Loading />}>
      <TagList />
    </UserActiveTags.Provider>
  );
}

const useStyles = makeStyles((theme) => ({
  // style
}));

function TagList() {
  const { root, chip } = useStyles();
  const tagData = useService(UserActiveTags);

  const handleDelete = (key) => {
    //delete
  };
  const handleSubmit = (key) => {
    //submit
  };

  const tagList = tagData.map(({ active, key, label }) => {
    const props = active === 0
      ? { variant: 'outlined', onDelete: () => handleSubmit(key), deleteIcon: <DoneIcon /> }
      : { variant: 'default', onDelete: () => handleDelete(key) };

    return (
      <li key={key}>
        <Chip
          color="secondary"
          label={label}
          className={chip}
          {...props}
        />
      </li>
    );
  });

  return (
    <Paper variant="outlined" square={true} component="span" className={root}>
      {tagList}
    </Paper>
  );
}

如果您需要tagData保持有状态,那么

const tagData = useService(UserActiveTags);

需要更新为此:

const initialTagData = useService(UserActiveTags);
const [tagData, setTagData] = useState(initialTagData);

useEffect(() => {
  setTagData(initialTagData);
}, [initialTagData]);

答案 1 :(得分:0)

我想你可以这样,

在您的useEffect()中,

const result = await axios.post('/user/activetag');
const filteredTags = tagData.map((e) => {
    const checkActive = result.data.some(i => i.tag_id == e.key);
    if(checkActive){
      const temp = {...e};
      temp.active = 1;
      return temp;
    }
   return e;
});

setTagData(filteredTags);

希望有效!