首页 > 解决方案 > 从 useState Hook React 渲染项目

问题描述

我已经useEffect使用钩子调用了我的api并存储了项目数组,useState但是我发现很难将这些项目呈现到自定义组件中,该组件也将传递数据。

这是我的反应片段:

export default function CreateCast() {

 const [open, setOpen] = useState(false);
 const [bibleCastItems, setBibleCastItems] = useState([]);

 const classes = useStyles();

 const fabStyle = {
   bottom: 50.0,
   right: 30.0,
   position: "fixed"
 };

 useEffect(()=>{
   async function fetchData(){
    var items = await APIService.getAllBibleCasts();
    // console.log(items);
    // console.log(items.data.bibleCasts);
    setBibleCastItems([items.data.bibleCasts]); 
    // items.data.bibleCasts.length > 0 ? setBibleCastItems([items.data.bibleCasts]) 
    // : setBibleCastItems([]);
  }
  fetchData();
  }, []
);

// console.log('bibleCastItems length ' + bibleCastItems.length);

return (
  <GridContainer>
    <GridItem xs={12} sm={12} md={12}>
      <Card plain>
        <CardHeader plain color="primary">
         <div className={classes.container}>
           <div className={classes.left}>
           <h4 className={classes.cardTitleWhite}>All BibleCasts</h4>
           <p className={classes.cardCategoryWhite}>
             Powered by our friends from <b>Unicorn Tech Consultants</b>{" "}
           </p>
         </div>
        </div>
       </CardHeader>
       <CardBody>
         {
           bibleCastItems.map((item, index) => <CastItem key={index} bibleCast={item[index]}/>) // this is where I'm facing issue
           // bibleCastItems.map((item, index) => {
            // console.log(item);
            // setMyItem(item);
            // return <div key={index}>{index}</div>
          // })
        }
        <div className={classes.right}>
            <Fab style={fabStyle} onClick={handleClickOpen}>
              <AddIcon />
            </Fab>
            <UploadFormDialog 
              open={open}
              handleClose={handleClose}
            />
        </div>           
      </CardBody>
    </Card>
  </GridItem>
 </GridContainer>
);

function handleClickOpen(){
  setOpen(true);
};

function handleClose(){
  setOpen(false);
};

}

这是我在浏览器视图中的状态:[![state view][1]][1]

如何将此状态映射为组件列表?我对此感到困惑

如您所见,我正在使用对话框来创建新项目并在请求成功后关闭对话框。我在这里有一个疑问,我如何告诉托管对话框的主要组件已获取新数据并应将其添加到状态中?

我的主要问题是如何映射状态中的项目以返回<CastItem />组件列表

CastItem 组件片段

export default function CastItem(props) {

let {bibleCast} = props;

const classes = useStyles();

return <GridContainer>
    <GridItem xs={12} sm={6} md={4}>
        <Card>
            <CardHeader color="info" stats icon>
                <CardIcon color="info">
                    <Streams />
                </CardIcon>
            </CardHeader>

            <CardBody>
                <h3 className={classes.cardTitle}>{bibleCast.title}</h3>
                <p className={classes.cardCategory}> Reinhard Bonnke</p>
            </CardBody>
        </Card>
    </GridItem>
</GridContainer>
}

CastItem.propTypes = {
  bibleCast: PropTypes.object.isRequired,
}

控制台中 API 的 JSON 响应:

[![json response][2]][2]

如果您要创建一个状态变量来将此响应表示为一个列表并显示该列表,您将如何使用钩子来实现它。谢谢你。[1]:https ://i.stack.imgur.com/QkthN.png [2]:https ://i.stack.imgur.com/8Hf11.png

标签: reactjsstateuse-state

解决方案


您正在做的错误是在 CreateCast 组件中,表单 api 您已经再次获得了一个数组,您正在将它传递到一个数组中,所以它作为嵌套数组出现

这样做

useEffect(()=>{
   async function fetchData(){
    var items = await APIService.getAllBibleCasts();
    setBibleCastItems(items.data.bibleCasts); 
  }
  fetchData();
  }, []
);


对于映射这样做


{
           bibleCastItems.map((item, index) => <CastItem key={index} bibleCast={item}/>) 
        }

// 有关如何从子级更新父级的问题,请遵循以下

有两种方法可以在父组件中设置数据,一种是从 api 重新获取或从子组件传递给父组件并在那里更新状态

我在这里有一个示例,如何更新父级和子级,将名称添加到列表中,名称列表状态在此处的父组件中维护,子级将通过添加名称将值传递回父级

import { useState } from "react";
import Child from "./Child";

export default function Parent() {
  const [list, setList] = useState(["ram"]);

  const handleAddName = (name) => {
    if (name) {
      setList([name, ...list]);
  // or you can refetch the list from api here

    }
  };
  return (
    <div>
      <div style={{ float: "left" }}>
        <h1>I am a parent Component</h1>
        <ul>
          {list &&
            list.map((item) => {
              return <li key={item}>{item}</li>;
            })}
        </ul>
      </div>

      <Child handleSubmit={handleAddName} />
    </div>
  );
}

孩子


import { useState } from "react";

export default function Child(props) {
  const [name, setName] = useState("");

  const updateNameList = (name) => {
    if (name) {
      props.handleSubmit(name);
      //reset field after data is sent
      // you can also save data here making post request respective api
      setName("");

    }
  };

  return (
    <div style={{ float: "right" }}>
      <h1>I am a Child Component</h1>
      <p> Add names below</p>
      <br />
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <button onClick={() => updateNameList(name)}>Add</button>
    </div>
  );
}

请参阅此代码和框

编辑顽皮-hugle-bdt7k


推荐阅读