React 无状态功能组件 - Laravel
React Stateless Functional Components - Laravel
我设置了一个项目,laravel 作为后端 Api 提供者,React 作为前端管理器。
当我简单地渲染一些组件时,React 无状态功能组件工作得很好。
const [state, setState] = useState({data:someData})
我使用 useEffect 通过 Axios 从 API URL 中获取一些数据。很好
但是当我用setState改变一个组件的状态时,它不起作用。没有反映任何变化。它看起来像一个静态页面,即使我点击了 100 次具有点击事件的按钮。控制台很清楚。没有错误
我想知道为什么?我该如何修复它。
注意:Class基础组件没有这个问题。它完美呈现状态的任何更新
部分代码
const Users = (props) => {
const [state, setState] = useState({
dataPraticiens: {
data: [],
currentPage: 1,
PerPage: 3
},
loaded: false
});
useEffect(() => {
Axios.get('/api/users').then((r) => {
setState({
dataPraticiens: {
data: [...r.data.docs],
currentPage: 1,
PerPage: 3
} ,
loaded: true
});
}).catch((er)=> {
console.log(er);
})
},[state.loaded]);
const changePage = (event) => {
let nS = state;
nS.dataPraticiens.currentPage = Number(event.target.id);
nS.loaded = false;
setState(nS);
// log the state and yeah, state changes but not reflected in the page
}
const indexOfLast = state.dataPraticiens.currentPage * state.dataPraticiens.PerPage;
const indexOfFirst = indexOfLast - state.dataPraticiens.PerPage;
const current = state.dataPraticiens.data.slice(indexOfFirst, indexOfLast);
const pageN = [];
for (let i = 1; i <= Math.ceil(state.dataPraticiens.data.length / state.dataPraticiens.PerPage); i++) {
pageN.push(i);
}
const renderPageN = pageN.map(num => {
return (
<li
key={num}
id={num}
onClick={changePage} // Not work here.
>
{num}
</li>
);
});
return (
{current.map((value, index) => {
return <React.Fragment key={index}>
<li>{value}</li>
</React.Fragment>
})}
<ul>
{renderPageN} // pages number`
</ul>
)}
在useEffect
中你应该使用一个空数组[]
来表示你希望效果只执行一次。使用 [state.loaded]
会在每次状态更新时重置状态,因为状态更新会导致 state.loaded
发生变化,而这种变化会触发效果挂钩。
另一件事是你不应该在这里直接改变状态:
let nS = state;
nS.dataPraticiens.currentPage = Number(event.target.id);
nS.loaded = false;
setState(nS);
请注意,nS
只是对同一状态对象的引用,因此您在技术上直接修改状态可能会导致未定义的行为和奇怪的错误。您应该构建状态对象的新副本:
const newState = {
dataPraticiens: {
...state.dataPraticiens,
currentPage: Number(event.target.id)
},
loaded: false
};
setState(newState);
来自 React docs:
NEVER mutate this.state
directly, as calling setState()
afterwards may replace the mutation you made. Treat this.state
as if it were immutable.
我设置了一个项目,laravel 作为后端 Api 提供者,React 作为前端管理器。 当我简单地渲染一些组件时,React 无状态功能组件工作得很好。
const [state, setState] = useState({data:someData})
我使用 useEffect 通过 Axios 从 API URL 中获取一些数据。很好
但是当我用setState改变一个组件的状态时,它不起作用。没有反映任何变化。它看起来像一个静态页面,即使我点击了 100 次具有点击事件的按钮。控制台很清楚。没有错误
我想知道为什么?我该如何修复它。
注意:Class基础组件没有这个问题。它完美呈现状态的任何更新
部分代码
const Users = (props) => {
const [state, setState] = useState({
dataPraticiens: {
data: [],
currentPage: 1,
PerPage: 3
},
loaded: false
});
useEffect(() => {
Axios.get('/api/users').then((r) => {
setState({
dataPraticiens: {
data: [...r.data.docs],
currentPage: 1,
PerPage: 3
} ,
loaded: true
});
}).catch((er)=> {
console.log(er);
})
},[state.loaded]);
const changePage = (event) => {
let nS = state;
nS.dataPraticiens.currentPage = Number(event.target.id);
nS.loaded = false;
setState(nS);
// log the state and yeah, state changes but not reflected in the page
}
const indexOfLast = state.dataPraticiens.currentPage * state.dataPraticiens.PerPage;
const indexOfFirst = indexOfLast - state.dataPraticiens.PerPage;
const current = state.dataPraticiens.data.slice(indexOfFirst, indexOfLast);
const pageN = [];
for (let i = 1; i <= Math.ceil(state.dataPraticiens.data.length / state.dataPraticiens.PerPage); i++) {
pageN.push(i);
}
const renderPageN = pageN.map(num => {
return (
<li
key={num}
id={num}
onClick={changePage} // Not work here.
>
{num}
</li>
);
});
return (
{current.map((value, index) => {
return <React.Fragment key={index}>
<li>{value}</li>
</React.Fragment>
})}
<ul>
{renderPageN} // pages number`
</ul>
)}
在useEffect
中你应该使用一个空数组[]
来表示你希望效果只执行一次。使用 [state.loaded]
会在每次状态更新时重置状态,因为状态更新会导致 state.loaded
发生变化,而这种变化会触发效果挂钩。
另一件事是你不应该在这里直接改变状态:
let nS = state;
nS.dataPraticiens.currentPage = Number(event.target.id);
nS.loaded = false;
setState(nS);
请注意,nS
只是对同一状态对象的引用,因此您在技术上直接修改状态可能会导致未定义的行为和奇怪的错误。您应该构建状态对象的新副本:
const newState = {
dataPraticiens: {
...state.dataPraticiens,
currentPage: Number(event.target.id)
},
loaded: false
};
setState(newState);
来自 React docs:
NEVER mutate
this.state
directly, as callingsetState()
afterwards may replace the mutation you made. Treatthis.state
as if it were immutable.