如何将我的 API 中的数据设置为我的反应组件的初始状态?

Posted

技术标签:

【中文标题】如何将我的 API 中的数据设置为我的反应组件的初始状态?【英文标题】:How to set the data from my API as initial state for my react component? 【发布时间】: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`  />
                <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 组件的初始状态!

【问题讨论】:

【参考方案1】:

几个问题:

    您为user 状态提供了一个真实的初始值,因此条件渲染没有像您预期的那样工作。 IE。因为 user 是 (),所以 if (user) 检查为真,并且您尝试呈现未定义的属性。 您将 JSX 存储在组件状态中,这是 React 中的一种反模式。 您在函数组件的主体中声明 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`  />
        <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>
    </>
  );

【讨论】:

谢谢德鲁!从三个小时开始,我就被这个问题困住了。我将使用这种方式在任何地方渲染组件。

以上是关于如何将我的 API 中的数据设置为我的反应组件的初始状态?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Redux Promise 为我的组件获得已解决的承诺?

如何在 Delphi 2009 中为我的组件设置 Tool Palette 组件图标?

React:如何将我的 ajax api 调用移动到一个单独的组件中?

我在哪里为我的图像设置缓存信息?

从子组件过滤数组数据表

从子组件中过滤数组数据表