在某些 React 状态更新后如何获取数据(通过 GET)?
How do I fetch data (via GET) after some React state updates?
当用户单击其中一个 orderBy 按钮时(通过 name/email/date)- 用户应该从服务器获取新的呈现结果(发送新的获取请求)- 页面分页也是如此.
设置 this.setState({ [thestate]: [newStateVar] })
本身并不能完成工作 ;)
复制这一行是不是“一个好习惯”:
this.setState({
tickets: await api.getTickets(this.state.currentOrder, this.state.page),
});
从componentDidMount()
改写?甚至更好——创建一个只执行此操作的方法——发送一个包含所有变量的获取请求——并在我需要重新渲染时调用它。 (我什至可以从 componentDidMount()
中删除这些行,而不是重写这些行。
这是正确的方法吗?
我一直认为只要 DOM 发生任何变化(例如 orderBy btns :active
class/style 发生变化)——所有可以更新的东西都会更新。我现在明白了吗?错了?
编辑:哦,如果你看到其他值得一提的东西来启发我 - 请做。
import React from 'react';
import './App.scss';
import Pagi from './components/pagination/pagi';
export type AppState = {
tickets?: Ticket[],
currentOrder: string,
page: number,
}
const api = createApiClient();
export class App extends React.PureComponent<{}, AppState> {
state: AppState = {
currentOrder: 'date',
page: 1
}
async componentDidMount() {
this.setState({
tickets: await api....
});
}
componentDidUpdate(pP:any, pS:any, sS:any) {
if (this.state.page !== pS.page) {
this.setState({ page: this.state.page })
}
if (this.state.currentOrder !== pS.currentOrder) {
this.setState({ currentOrder: this.state.currentOrder })
}
}
renderTickets = (tickets) => {
const filteredTickets = tickets
.filter(...);
return (
<ul>
{showtkts}
</ul>
);
}
setOrder = (order:any) => {
console.log(this.state.currentOrder)
this.setState({
currentOrder: order.target.value,
});
}
setPage = (pageNum: number) => {
this.setState({
page: pageNum
})
}
render() {
const {tickets} = this.state;
return (<main>
<span> Order by: </span>
<button value='name' onClick={this.setOrder} className={ (this.state.currentOrder === 'name') ? 'selectedOrderItem' : '' }>
{/* <span role="img" aria-label="name"></span> */}
Name
</button>
<button value='email' onClick={this.setOrder} className={ (this.state.currentOrder === 'email') ? 'selectedOrderItem' : '' }>
{/* <span role="img" aria-label="email"></span> */}
Email
</button>
<button value='date' onClick={this.setOrder} className={ (this.state.currentOrder === 'date') ? 'selectedOrderItem' : '' }>
{/* <span role="img" aria-label="date"></span> */}
Date
</button>
</div>
<div className='resultsCount'>
{ tickets ? <div className='results'>Showing {tickets.length} results</div> : null }
{ (this.state.hidden === 0) ? '' : ((this.state.hidden === 1) ? <div className='results'>(1 ticket is hidden</div> : <div className='results'>({this.state.hidden} hidden tickets </div>) }
{ (this.state.hidden > 0) ? <div className='results showHiddenBtn' onClick={this.showHiddenTickets}>- restore) </div> : null }
</div>
<div>
{getTkts here}
</div>
<Pagi pages={tickets ? tickets.length : 1}/>
}
}
export default App;
How do I fetch data (via GET) after some React state updates?
我认为你没有正确处理这个问题,流程应该是:
- 用户操作
- 获取数据
- (异步)状态更新
- 渲染
而不是渲染触发数据获取的另一种方式。
我建议重新考虑您的组件设计,而不是试图让有缺陷的流程与您当前的实现一起工作。
示例请参见此代码框:https://codesandbox.io/s/boring-matsumoto-ti9ot?file=/src/App.js
编辑:
来自以下评论:
Hi nick i have an other question reguarding to this. If i order results by email (that resets the page to 1 and tickets to []? how do i go from clicking a filter to fetch to state update if i need the state updated before fetching data.
同样,不必担心手动对渲染和更新进行计时,只需管理您的状态并让 React 处理更新和渲染,例如:
const [data, setData] = useState();
const [loading, setLoading] = useState(true);
const handleFetch = () => {
fetchData().then((res) => {
setData(res.data);
setLoading(false);
});
};
// Onload, fetch data and set loading to false when complete
useEffect(() => {
handleFetch();
}, []);
return (
<>
{loading ? <div>Loading...</div> : <div>data: {data}</div>}
<button onClick={handleFetch}>Click me to cause refetch data</button>
</>
);
对于您的用例,您要么只在加载完成时显示数据(有效地将数据重置为 []
),要么显示某种占位符直到呈现数据。而不是将状态设置为空,然后获取,然后再次设置状态。
当用户单击其中一个 orderBy 按钮时(通过 name/email/date)- 用户应该从服务器获取新的呈现结果(发送新的获取请求)- 页面分页也是如此.
设置 this.setState({ [thestate]: [newStateVar] })
本身并不能完成工作 ;)
复制这一行是不是“一个好习惯”:
this.setState({
tickets: await api.getTickets(this.state.currentOrder, this.state.page),
});
从componentDidMount()
改写?甚至更好——创建一个只执行此操作的方法——发送一个包含所有变量的获取请求——并在我需要重新渲染时调用它。 (我什至可以从 componentDidMount()
中删除这些行,而不是重写这些行。
这是正确的方法吗?
我一直认为只要 DOM 发生任何变化(例如 orderBy btns :active
class/style 发生变化)——所有可以更新的东西都会更新。我现在明白了吗?错了?
编辑:哦,如果你看到其他值得一提的东西来启发我 - 请做。
import React from 'react';
import './App.scss';
import Pagi from './components/pagination/pagi';
export type AppState = {
tickets?: Ticket[],
currentOrder: string,
page: number,
}
const api = createApiClient();
export class App extends React.PureComponent<{}, AppState> {
state: AppState = {
currentOrder: 'date',
page: 1
}
async componentDidMount() {
this.setState({
tickets: await api....
});
}
componentDidUpdate(pP:any, pS:any, sS:any) {
if (this.state.page !== pS.page) {
this.setState({ page: this.state.page })
}
if (this.state.currentOrder !== pS.currentOrder) {
this.setState({ currentOrder: this.state.currentOrder })
}
}
renderTickets = (tickets) => {
const filteredTickets = tickets
.filter(...);
return (
<ul>
{showtkts}
</ul>
);
}
setOrder = (order:any) => {
console.log(this.state.currentOrder)
this.setState({
currentOrder: order.target.value,
});
}
setPage = (pageNum: number) => {
this.setState({
page: pageNum
})
}
render() {
const {tickets} = this.state;
return (<main>
<span> Order by: </span>
<button value='name' onClick={this.setOrder} className={ (this.state.currentOrder === 'name') ? 'selectedOrderItem' : '' }>
{/* <span role="img" aria-label="name"></span> */}
Name
</button>
<button value='email' onClick={this.setOrder} className={ (this.state.currentOrder === 'email') ? 'selectedOrderItem' : '' }>
{/* <span role="img" aria-label="email"></span> */}
Email
</button>
<button value='date' onClick={this.setOrder} className={ (this.state.currentOrder === 'date') ? 'selectedOrderItem' : '' }>
{/* <span role="img" aria-label="date"></span> */}
Date
</button>
</div>
<div className='resultsCount'>
{ tickets ? <div className='results'>Showing {tickets.length} results</div> : null }
{ (this.state.hidden === 0) ? '' : ((this.state.hidden === 1) ? <div className='results'>(1 ticket is hidden</div> : <div className='results'>({this.state.hidden} hidden tickets </div>) }
{ (this.state.hidden > 0) ? <div className='results showHiddenBtn' onClick={this.showHiddenTickets}>- restore) </div> : null }
</div>
<div>
{getTkts here}
</div>
<Pagi pages={tickets ? tickets.length : 1}/>
}
}
export default App;
How do I fetch data (via GET) after some React state updates?
我认为你没有正确处理这个问题,流程应该是:
- 用户操作
- 获取数据
- (异步)状态更新
- 渲染
而不是渲染触发数据获取的另一种方式。
我建议重新考虑您的组件设计,而不是试图让有缺陷的流程与您当前的实现一起工作。
示例请参见此代码框:https://codesandbox.io/s/boring-matsumoto-ti9ot?file=/src/App.js
编辑:
来自以下评论:
Hi nick i have an other question reguarding to this. If i order results by email (that resets the page to 1 and tickets to []? how do i go from clicking a filter to fetch to state update if i need the state updated before fetching data.
同样,不必担心手动对渲染和更新进行计时,只需管理您的状态并让 React 处理更新和渲染,例如:
const [data, setData] = useState();
const [loading, setLoading] = useState(true);
const handleFetch = () => {
fetchData().then((res) => {
setData(res.data);
setLoading(false);
});
};
// Onload, fetch data and set loading to false when complete
useEffect(() => {
handleFetch();
}, []);
return (
<>
{loading ? <div>Loading...</div> : <div>data: {data}</div>}
<button onClick={handleFetch}>Click me to cause refetch data</button>
</>
);
对于您的用例,您要么只在加载完成时显示数据(有效地将数据重置为 []
),要么显示某种占位符直到呈现数据。而不是将状态设置为空,然后获取,然后再次设置状态。