【问题标题】:How to set the data from my API as initial state for my react component?如何将我的 API 中的数据设置为我的反应组件的初始状态?
【发布时间】:2021-10-19 23:17:28
【问题描述】:

我正在为我的网站制作个人资料页面,但是当我最初呈现组件时,来自 API 的数据不知何故不会以我为 About、Blog 或 Stats 制作的初始“状态”加载。

但是,当我再次单击“关于”时,API 数据被呈现。

如果我能表达我的观点,IDK,但这就是我的反应功能组件的样子:

const Profile = () => {
    let history = useHistory();
    const [user, setUser] = useState({});
    useEffect(() => {
        async function fetchMyAPI() {
           try {
               let res = await api.get('user/isLoggedIn', { withCredentials: true });
               if (res.data.user) {
                   setUser(res.data.user);
               }
           }catch (err) {
                history.push('/login');
           }
       }
       fetchMyAPI();
    }, []);

    const About = ({ user }) => {
        if (user)
            return (
                <div className="about_wrapper">
                    <p className="name_about">{`${user.name}`}</p>
                    <p className="email_about">{`${user.email}`}</p>
                    <p><FontAwesomeIcon icon={faPen} />{`  ${user.niche}`}</p>
                    <p><FontAwesomeIcon icon={faAlignLeft} />{` ${user.job}`}</p>
                    <p className="description_about"><FontAwesomeIcon icon={faAddressBook} />{` ${user.description}`}</p>
                </div>
            );
        else
            return (
                <h3>Loading..</h3>
            );
}
    const Blogs = (props) => {
        return (
            <>
            </>
        );
    }
    const Stats = (props) => {
        return (
            <>
            </>
        );
    }

    const [state, stateSetter] = useState(<About user={user}/>);

    const clickHandler = (e) => {
        e.preventDefault()
        const nav = document.querySelectorAll('.info_links');
        switch (e.target.textContent) {
            case 'About':
                nav[1].classList.remove('un-p');
                nav[2].classList.remove('un-p');
                stateSetter(<About user={user}/>);
                break;
            case 'Stats':
                nav[0].classList.remove('un-p');
                nav[1].classList.remove('un-p');
                stateSetter(<Stats user={user}/>);
                break;
            case 'Blogs':
                nav[0].classList.remove('un-p');
                nav[2].classList.remove('un-p');
                stateSetter(<Blogs user={user}/>);
                break;
            default:
             console.log('error')
        }
        e.target.classList.add('un-p');
    }

    return (
        <>
            <Navbar />
            <div>
                <div className="CoverImage FlexEmbed FlexEmbed--2by1" style={{ backgroundImage: `url(${user.cover}})` }}></div>
                <img className="avatar" src={`${user.dp}`} alt="Girl in a jacket" />
                <div className="info">
                    <p className="info_links link-grow un un-p" onClick={clickHandler}>About</p>
                    <p className="info_links un" onClick={clickHandler}>Blogs</p>
                    <p className="info_links un" onClick={clickHandler}>Stats</p>
                </div>
                {state}
            </div>
        </>
    );
}

导出默认配置文件

我想将我的 API 中的数据设置为我的 react 组件的初始状态!

【问题讨论】:

    标签: reactjs api axios use-effect use-state


    【解决方案1】:

    几个问题:

    1. 您为user 状态提供了一个真实的初始值,因此条件渲染没有像您预期的那样工作。 IE。因为 user 是 ({}),所以 if (user) 检查为真,并且您尝试呈现未定义的属性。
    2. 您将 JSX 存储在组件状态中,这是 React 中的一种反模式。
    3. 您在函数组件的主体中声明 React 组件,这将产生在每个渲染周期创建 组件并卸载和重新安装组件的效果。这可能会对性能产生不利影响。

    AboutBlogsStats 移出Profile 组件,以便它们具有稳定的引用。

    const About = ({ user }) => {
      if (user)
        return (
          <div className="about_wrapper">
            <p className="name_about">{`${user.name}`}</p>
            <p className="email_about">{`${user.email}`}</p>
            <p><FontAwesomeIcon icon={faPen} />{`${user.niche}`}</p>
            <p><FontAwesomeIcon icon={faAlignLeft} />{`${user.job}`}</p>
            <p className="description_about">
              <FontAwesomeIcon icon={faAddressBook} />
              {`${user.description}`}
            </p>
          </div>
        );
      else
        return (
          <h3>Loading..</h3>
        );
    };
    
    const Blogs = (props) => {
      return (
        <>
        </>
      );
    };
    
    const Stats = (props) => {
      return (
        <>
        </>
      );
    };
    

    将组件“类型”存储在状态中并有条件地渲染它们,将user 状态传递给它们。

    const Profile = () => {
      const history = useHistory();
      const [user, setUser] = useState(); // <-- undefined, falsey
      const [state, stateSetter] = useState('About'); // <-- use type
    
      useEffect(() => {
        async function fetchMyAPI() {
          try {
            let res = await api.get('user/isLoggedIn', { withCredentials: true });
            if (res.data.user) {
              setUser(res.data.user);
            }
          } catch(err) {
            history.push('/login');
          }
        }
        fetchMyAPI();
      }, []);
    
      const clickHandler = (e) => {
        e.preventDefault()
        const nav = document.querySelectorAll('.info_links');
        switch (e.target.textContent) {
          case 'About':
            nav[1].classList.remove('un-p');
            nav[2].classList.remove('un-p');
            stateSetter('About'); // <-- update state type
            break;
          case 'Stats':
            nav[0].classList.remove('un-p');
            nav[1].classList.remove('un-p');
            stateSetter('Stats'); // <-- update state type
            break;
          case 'Blogs':
            nav[0].classList.remove('un-p');
            nav[2].classList.remove('un-p');
            stateSetter('Blogs'); // <-- update state type
            break;
          default:
            console.log('error')
        }
        e.target.classList.add('un-p');
      }
    
      return (
        <>
          <Navbar />
          <div>
            <div
              className="CoverImage FlexEmbed FlexEmbed--2by1"
              style={{ backgroundImage: `url(${user.cover}})` }}>
            </div>
            <img className="avatar" src={`${user.dp}`} alt="Girl in a jacket" />
            <div className="info">
              <p className="info_links link-grow un un-p" onClick={clickHandler}>About</p>
              <p className="info_links un" onClick={clickHandler}>Blogs</p>
              <p className="info_links un" onClick={clickHandler}>Stats</p>
            </div>
            {state === 'About' && <About user={user} />}
            {state === 'Stats' && <Stats user={user} />}
            {state === 'Blogs' && <Blogs user={user} />}
          </div>
        </>
      );
    }
    

    【讨论】:

    • 谢谢德鲁!从三个小时开始,我就被这个问题困住了。我将使用这种方式在任何地方渲染组件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    相关资源
    最近更新 更多