React onClick更改分页数据落后一步

时间:2019-10-11 01:37:34

标签: javascript reactjs react-hooks

编写简单的前端分页,带有“下一步”和“后退”按钮。当我使用console.log(state)时,单击按钮时状态似乎正在根据我的计划进行更改。但是该网页从上一页开始显示状态数据。


import React, { useEffect, useState } from "react";
import { useStateValue } from "../state";
import getChar from "../api/index";
import Spinner from "../components/loading"

export default function Characters(props) {
  // access state and dispatch functions here
  const [state, dispatch] = useStateValue();
  const [loading, setLoading] = useState(true);
  const [index, setIndex] = useState(0);
  let [page, setPage] = useState(1);


  const apiCall = async (num) => {
    const first = (4 * num) - 4;
    const last = (4 * num) - 1;
    const res = await getChar.getCharacters();
    const display = res.results.filter((char, index) => {
      return (index >= first && index <= last);
    })
    await dispatch({
      type: 'GET_CHARACTERS',
      data: display
    });
    setLoading(false)
    setIndex(res.results.length)
  }

  // move to next page
  const next = () => {
    const newPage = page + 1;
    const maxPages = Math.ceil(index / 4);
    if (newPage > maxPages) {
      setPage(maxPages)
      apiCall(maxPages)
    } else {
      setPage(newPage)
      apiCall(newPage)
    }
  }

  // move back a page
  const back = () => {
    const newPage = page - 1;
    if (newPage === 0) {
      setPage(1)
      apiCall(1)
    } else {
      setPage(newPage)
      apiCall(newPage)
    }
  }

  useEffect(() => {
    apiCall(1)
  }, []);

  if (loading) {
    return <div><Spinner /></div>
  }

  return (
    <div>
      <h1>Characters Page</h1>
      {
        state.characters.map((char, index)=> (
          (char.starships.length === 0) ?
            <div className="List" key={index}>
                <h3 className="character">
                  {char.name}
                </h3>
            </div>
          :
            <div className="List" key={index}>
                <h3 className="character">
                  {char.name} - pilot
                </h3>
            </div>
        ))
      }
    <button onClick={back}>back</button>
    <button onClick={next}>next</button>
    </div>
  );
}

export default function reducer(state, action) { 
  switch (action.type) { 
    case "GET_CHARACTERS": 
      state.characters = action.data;
      return state; default: return state; 
  } 
}

在单击直到分页的最后一页之前,显示以前的状态数据。在单击返回按钮反之亦然之前,将不显示分页数据的最后一位。

1 个答案:

答案 0 :(得分:0)

反应无法检测到可变对象中的更改。每个reducer中都应返回一个新的状态对象。

case "GET_CHARACTERS": 
    state.characters = action.data;
    return {...state};

case "GET_CHARACTERS": 
    return {...state, characters: action.data};

一些有用的信息:

这是可变对象的演示。

var a= {name:1}
var b = a;
b.name=2
var result = Object.is(a,b)
console.log(result) // true