Javascript 为Gf'构建应用程序;s生日-在Redux中更新状态时遇到问题

Javascript 为Gf'构建应用程序;s生日-在Redux中更新状态时遇到问题,javascript,reactjs,redux,state,Javascript,Reactjs,Redux,State,所以我正在为我的女朋友的生日开发一个园艺应用程序,帮助她跟踪她的花园,而我的最后期限(lol)很快就要到了!版本1的基本实现已经基本完成,但我可以在不刷新页面的情况下获取想要显示的数据。这是我第一次使用Redux/尝试实现用户身份验证,所以我可能只是装傻,但是: 从本质上讲,应用程序目前的构建方式,我从州政府那里获得了一系列关于花园中植物的数据: const plants = useSelector(state => state.plant.plants); 然后在我的useEffect

所以我正在为我的女朋友的生日开发一个园艺应用程序,帮助她跟踪她的花园,而我的最后期限(lol)很快就要到了!版本1的基本实现已经基本完成,但我可以在不刷新页面的情况下获取想要显示的数据。这是我第一次使用Redux/尝试实现用户身份验证,所以我可能只是装傻,但是:

从本质上讲,应用程序目前的构建方式,我从州政府那里获得了一系列关于花园中植物的数据:

const plants = useSelector(state => state.plant.plants);
然后在我的useEffect钩子中,在用户经过身份验证后,我过滤植物列表以创建一个新列表,其中仅包含该特定用户添加的植物:

useEffect(() => {
dispatch(getPlants()); }, [dispatch]);
useEffect(() => { if (user && isAuthenticated) { const usersGarden = plants.filter(plant => plant.addedBy._id === user._id) setGarden(usersGarden) } }, [user, isAuthenticated, plants])
这个新的,用户特定的植物列表应该存储在国家(花园和setGarden),它是。。。问题是,在我刷新页面一次之前,它不会出现

这就是发生的情况,顺序如下:

注销时:-我的“state”console.log立即显示数据-“plants”console.log(从state获取植物的useSelector钩子)最终会获取植物,尽管它记录了两次为空(我也不确定为什么记录了这么多次)-花园是空的

控制台/用户界面图像:

  • 登录后:-状态和植物控制台日志有数据-Garden console.log仍然没有用户植物的筛选列表:((((((((
  • 控制台/用户界面图像:

  • 登录并刷新页面一次后:-garden突然有了我想要的数据,一切都神奇地出现了(如果我不需要刷新的话)
  • 控制台/用户界面图像:

    我做错了什么=/

    完整代码:

    import React, { useState, useEffect } from 'react';
    import { Container, Card, CardBody, CardTitle, Button, Row, Col } from 'reactstrap';
    import { useSelector, useDispatch } from 'react-redux';
    import { getPlants, deletePlant } from '../actions/plantActions';
    import PlantModal from './PlantModal';
    import PlantDetailModal from './PlantDetailModal';
    
    
    export const Garden = () => {
      const plants = useSelector(state => state.plant.plants);
      const dispatch = useDispatch();
      const auth = useSelector(state => state.auth);
      const { user, isAuthenticated } = auth;
      const [garden, setGarden] = useState([])
    
      console.log('state', useSelector(state => state))
      console.log('plants', plants)
    
      useEffect(() => {
        dispatch(getPlants());
      }, [dispatch]);
    
      useEffect(() => {
        if (user && isAuthenticated) {
          const usersGarden = plants.filter(plant => plant.addedBy._id === user._id)
          setGarden(usersGarden)
        }
      }, [user, isAuthenticated, plants])
    
      console.log('garden', garden)
    
    
      if (user && isAuthenticated) {
        return (
          <div>
            <Row>
              <Col xs="auto" className="mt-1">
                <h1 style={{ fontSize: "2.5rem", color: "#ffffb5" }}>{user ? user.name : null}'s Garden</h1>
              </Col>
              <Col className="py-2 text-right">
                <PlantModal />
              </Col>
            </Row>
            <Container fluid style={{ border: "3px solid #ffffb5", backgroundColor: "#99b898", borderRadius: "4px" }}>
              <Row>
                {garden.map(({ _id, name, description, growingZone, grownFromSeed, heirloom, idealTemp, imageURL, plantingDate, scientificName, seedDepth, soilType, spacing, sproutsIn, sunlight, timeToHarvest, watering }) => (
                  <Col key={_id} className="my-3 d-flex justify-content-center">
                    <Card className="text-center" body style={{ width: "275px", maxWidth: "275px" }}>
                      <Row className="text-right" style={{ marginTop: "-12px" }}>
                        <Col>
                          {isAuthenticated ? (
                            <Button
                              close
                              onClick={() => {
                                dispatch(deletePlant(_id));
                              }}
                            >
                            </Button>
                          ) : null}
                        </Col>
                      </Row>
                      <Row>
                        <Col>
                          <CardTitle>
                            <h4>{name}</h4>
                            <hr />
                            <h6 className="font-italic text-muted">{scientificName}</h6>
                          </CardTitle>
                        </Col>
                      </Row>
                      <CardBody className="p-0">
                        {<img className="rounded mt-3 mb-0 p-0" style={{ width: "230px", maxWidth: "230px" }} src={imageURL} alt="plant"></img> || <div className="rounded mb-4" style={{ width: "200px", height: "100px", backgroundColor: "seagreen" }}></div>}
                        <PlantDetailModal 
                            name={name} 
                            description={description} 
                            growingZone={growingZone} 
                            grownFromSeed={grownFromSeed} 
                            heirloom={heirloom} 
                            idealTemp={idealTemp} 
                            imageURL={imageURL} 
                            plantingDate={plantingDate} 
                            scientificName={scientificName} 
                            seedDepth={seedDepth} 
                            soilType={soilType} 
                            spacing={spacing} 
                            sproutsIn={sproutsIn} 
                            sunlight={sunlight} 
                            timeToHarvest={timeToHarvest} 
                            watering={watering} />
                      </CardBody>
                    </Card>
                  </Col>
                ))}
              </Row>
            </Container>
          </div >
        )
      }
    
      return <h1 className="text-white text-center mt-5 font-italic pt-5">~ Please Sign In ~</h1>
    }
    
    export default Garden;
    

    “我做错了什么?”-这肯定不是你想要的答案,但当我看到第一段中的“身份验证”一词时,我开始怀疑。这是否有一点可能(可能?)这样的功能实际上会降低你的应用程序的吸引力?登录是我处理其他人的东西所做的。如果我有一个为我编写的应用程序,为什么我要登录?作者至少可以做的是减轻我的吸引力。她也是一名开发人员,她并不打算永远是唯一的用户。最终我想建立一个新的应用程序植物生长规格的公共API,但我的意图是从这个开始作为礼物送给她,因为她喜欢园艺,我在工作和学习编程之间。因此,学习用户授权和Redux。或者至少尝试。:)好主意,但有点离题…确保准备好备用礼物,比如一些花,一些浪漫的东西。在截止日期前制定B计划从来都不是一个坏主意。现在是关于主题。我同意enhzflep,从简单开始。身份验证通常是一个棘手的主题,可以稍后添加。localStorage.setItem(“花园”,JSON.stringify(state.plant.plants))将其写入localStorage可能会让您达到目的。它将保存在她的浏览器存储中--有点像本地应用程序。然后,当您要加载花园时,只需让garden=JSON.parse(localStorage.getItem(“花园”));查看localStorage at:这是最快捷最简单的方法,您可以稍后提供将存储的花园导出到其他浏览器的方法。
    import {
      GET_PLANTS,
      ADD_PLANT,
      DELETE_PLANT,
      PLANTS_LOADING
    } from '../actions/types';
    
    const initialState = {
      plants: [],
      loading: false
    };
    
    export default function (state = initialState, action) {
      switch (action.type) {
        case GET_PLANTS:
          return {
            ...state,
            plants: action.payload,
            loading: false
          };
        case DELETE_PLANT:
          return {
            ...state,
            plants: state.plants.filter(plant => plant._id !== action.payload)
          };
        case ADD_PLANT:
          return {
            ...state,
            plants: [action.payload, ...state.plants]
          };
        case PLANTS_LOADING:
          return {
            ...state,
            loading: true
          };
        default:
          return state;
      }
    }