用数据初始化useState并没有刷新页面。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用数据初始化useState并没有刷新页面。相关的知识,希望对你有一定的参考价值。
我有一条路线。
<Route path="/projects/:handle" component={Project} />
当我浏览到i. e. ,页面加载成功 /projects/my-project-1
的时候,页面加载成功,但是如果我到了 /projects/my-other-project
,页面的内容保持不变(我的项目-1内容)。
的 match.params.handle
获取的数据,但useState仍然保留了(my-project-1)的数据。
const Project = ({ match }) => {
const projectContext = useContext(ProjectContext)
const [project] = useState(projectContext.getProject(match.params.handle))
// my-other-project
console.log(match.params.handle);
let proj = projectContext.getProject(match.params.handle);
// returns my-other-project
console.log(proj)
const [project] = useState(proj)
// this is still my-project-1 data
console.log(project);
return (
<>
<Row>
<Col sm={12} lg={12}>
<ProjectOverview projectContext={projectContext} project={project} />
</Col>
</Row>
</>
);
}
export default Project;
我加载组件数据的方式可能有什么问题,有没有更好的方法,也许是通过useEffect?有点儿 新的反应(和反应钩子))
答案
这不是你使用道具初始化状态的方式(我们将在一分钟内回到这个问题)。
一般来说,没有理由把道具复制到状态。只要使用道具就可以了。这就是它的作用。它基本上是你组件的状态,由父组件管理。所以。
const Project = ({ match }) => {
const projectContext = useContext(ProjectContext)
const project = projectContext.getProject(match.params.handle); // ***
return (
<>
<Row>
<Col sm={12} lg={12}>
<ProjectOverview projectContext={projectContext} project={project} />
</Col>
</Row>
</>
);
}
(附注: 没有必要使用那个片段,你可以返回这个片段) Row
直接)。)
如果 projectContext.getProject(match.params.handle)
是一个昂贵的操作,你可以通过以下方式来记忆 useMemo
:
const Project = ({ match }) => {
const projectContext = useContext(ProjectContext)
const project = useMemo(
() => projectContext.getProject(match.params.handle),
[match.params.handle]
);
return (
<>
<Row>
<Col sm={12} lg={12}>
<ProjectOverview projectContext={projectContext} project={project} />
</Col>
</Row>
</>
);
}
实例。
const { useState, useEffect, useMemo, useContext } = React;
const Row = props => <div {...props}/>;
const Col = props => <div {...props}/>;
const ProjectOverview = ({projectContext, project}) => {
return <div>Project: {project.name}</div>;
};
const contextValue = {
getProject(handle) {
console.log(`Getting project ${handle}...`);
// busy-wait half a second
const end = Date.now() + 500;
while (Date.now < end) {
// Wait -- NEVER BUSY WAIT LIKE THIS IN REAL CODE
}
return {name: `Project for handle ${handle}`};
}
};
const ProjectContext = React.createContext(contextValue);
const Project = ({ match }) => {
console.log(`Project called with handle = ${match.params.handle}`);
const projectContext = useContext(ProjectContext)
const project = useMemo(
() => {
console.log(`Recalcuating project from handle ${match.params.handle}`);
return projectContext.getProject(match.params.handle);
},
[match.params.handle]
);
console.log(`project is: "${project.name}"`);
// Note: Can't use <>...</> in Stack Snippets, we have
// to use the older React.Fragment syntax.
return (
<React.Fragment>
<Row>
<Col sm={12} lg={12}>
<ProjectOverview projectContext={projectContext} project={project} />
</Col>
</Row>
</React.Fragment>
);
}
const App = () => {
const [counter, setCounter] = useState(0);
const [handle, setHandle] = useState(1);
useEffect(() => {
if (handle < 3) {
setTimeout(() => {
setCounter(c => {
c = c == 0 ? 1 : 0;
if (c == 0) {
// Update the handle every two calls
setHandle(h => h + 1);
}
return c;
});
}, 800);
}
}, [handle, counter]);
return (
<ProjectContext.Provider value={contextValue}>
<Project match={{params: {handle}}} />
</ProjectContext.Provider>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
以上是关于用数据初始化useState并没有刷新页面。的主要内容,如果未能解决你的问题,请参考以下文章