如何将我的 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 组件,这将产生在每个渲染周期创建 新 组件并卸载和重新安装组件的效果。这可能会对性能产生不利影响。
将About
、Blogs
和Stats
移出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 组件图标?