react hooks改变state后,state还是没变

本人一直用vue,闲来无事学学react,于是把项目中的一个页面用react改写,但是问题很多。。。

如图是一个列表,可以根据类型筛选,列表也有滚动分页功能,当我选择新的类型筛选时,需要先清空之前的列表数据,重置页数,然后用新类型执行查找并显示新的数据,使用vue时我是这么写的:
image.png

created() {
    this.getQuestionList()
},
data() {
    return{
        pages: 1,
        dataList: [],
        type: '工艺'
    }
},
watch: {
    type(newVal) {
        this.doSearch()
    }
},
methods: {
  doSearch() {
    this.pages = 1 // 重置翻页页数
    this.dataList = [] // 清空原先列表
    this.getQuestionList() // 执行查询
  },
  getQuestionList() {
      let {data} = await questionListApi(this.pages, this.type)
      this.dataList = data
  }
}

vue中这样写完全没问题,但是我换成react hooks写,就不行了:

const [pages, setPages] = useState(1)
const [dataList, setDataList] = useState([])
const [type] = useState('工艺')

const doSearch = () => {
  setPages(1) // 重置翻页页数
  setDataList([]) // 清空原先列表
  getQuestionList() // 执行查询
}
const getQuestionList = () => {
  let {data} = await questionListApi(pages, type)
  setDataList(data)
}
// 监听type改变获取新数据
useEffect(() => {
    doSearch()
}, [type])
// 页面载入时获取数据
useEffect(() => {
    getQuestionList()
}, [])

所有的赋值操作都没有生效,导致执行新查询的时候pages参数是错的,原先的列表也没有清空,求问react hooks中这样的业务场景应该怎么写?另外ui部分的代码我就不写了,你们就当type会变化就行了。。。

阅读 6.5k
4 个回答

函数组件的最新state只能在下一次函数重新执行的时候拿到。你需要理解类组件和函数组件的区别。类组件有自己的实例,每次update只会重新执行render函数。而函数组件每次update都会重新执行整个函数。函数组件里的state更改,只能在下一次函数执行的时候拿到最新的值。

你的需求:

  1. mount时传入初始化的 typepage作为参数,请求接口拿数据。
  2. page 更改的时候,传入新的 page 值请求接口。
  3. type 更改的时候,传入初始的 page 和最新的 type 请求数据。
const defaultType = '工艺';
const defaultPage = 0;
const [page, setPage] = useState(defaultPage);
const [type, setType] = useState(defaultType);
const [list, setList] = useState([]);
const onPageChange = (newpage) => {
    setPage(newPage);
}
const onTypeChange = (newType) => {
    setPage(defaultPage);
    setType(newType);
}
useEffect(() => {
    const result = getData(page, type);
    setList(result);
}, [page,type]);

image.png

然后你该懂了。

setDataList 执行完成之后 pages 还不是最新值!
这两个函数执行完之后 整个函数组件重新执行 这个时候 pages 才是最新的值
所以 getQuestionList 里面取值 拿的就是 setPages 执行之前的值
要么把1 传入 getQuestionList
要么

useEffect(() => {
    let {data} = await questionListApi(pages, type)
  setDataList(data)
}, [pages])
新手上路,请多包涵

react-hook的执行方式是流式执行,所以当存在异步方法的时候,要使用useEffect监听某一个key(也就是state)的变化,来执行他的副作用。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进