英文:
content doesn't change after sorting react
问题
我有一个小的React应用。我想要实现按不同参数排序的功能,当您选择一个sortType时,下面的内容将根据这些标准进行排序。
我创建了一个函数,应该根据sortType返回带有必要参数的数据,但它不起作用。内容没有改变。
我认为这里可能有些错误,但我没能注意到,如果有人能帮助我,我会很高兴。
英文:
I've a small React app. I want to make it possible to sort by different parameters, when you select a sortType, the content below is sorted by those criteria.
I created a function that should return data already with the necessary parameters depending on the sortType, but it doesn't work. The content doesn't change.
I think that there is some kind of mistake here and I can’t notice it, I'll be glad if someone helps me with this
function MarkersPage() {
  const markers = useSelector((state) => state.data.markers);
  const [data, setData] = useState([...markers]);
  const [sortType, setSortType] = useState(1);
  const markerItem = (item) => {
    return (
      <div className="markers-item" key={item.id}>
        <div className="top-info">
          <div className="icon">
            <img
              src={
                item.isHome
                  ? "../assets/home-marker.png"
                  : "../assets/default-marker.png"
              }
              alt=""
            />
          </div>
          <div className="coords">
            <span>{item.coordinates[0].toFixed(5)}, </span>
            <span>{item.coordinates[1].toFixed(5)}</span>
          </div>
          <div className="btn-block">
            <button type="button" onClick={() => handleEdit(item)}>
              edit
            </button>
            <button
              type="button"
              onClick={() => dispatch(deleteMarker(item.id))}
            >
              delete
            </button>
          </div>
        </div>
        <div className="main-info">
          <div className="info">
            <h6>{item.title}</h6>
          </div>
          {item.note ? (
            <details className="note">
              <summary>Note:</summary> <p>{item.note}</p>
            </details>
          ) : (
            ""
          )}
        </div>
        <div className="bottom-info">
          <p className="postcode">{item.postcode}</p>
          <p className="country">{item.country}</p>
        </div>
      </div>
    );
  };
  const dataChanges = () => {
    if (sortType === 1) {
      console.log(1);
      return data.map((item) => {
        return markerItem(item);
      });
    }  
    if (sortType === 2) {
      console.log(2);
      return data.map((item) => {
        return markerItem(item);
      });
    } 
    if (sortType === 3) {
      console.log(3);
    return data
        .sort((a, b) => a.date - b.date)
        .map((item) => {
          return markerItem(item);
        });
    }
    if (sortType === 4) {
      console.log(4);
      return data
        .sort((a, b) => b.date - a.date)
        .map((item) => {
          return markerItem(item);
        });
    }
  };
  return (
    <div className="markerspage">
      <div className="container">
        <div
          className="markerspage-inner"
          style={editMode ? { filter: "blur(10px)" } : {}}
        >
          <div className="sort-bar">
            <select
              defaultValue={1}
              onChange={(event) => setSortType(event.target.value)}
            >
              <option value="1">All</option>
              <option value="2">Home</option>
              <option value="3">Date &#8593;</option>
              <option value="4">Date &#8595;</option>
            </select>
          </div>
          <div>
            {!markers ? (
              <div>No places</div>
            ) : (
              <div className="markers-items">{dataChanges()}</div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}
export default MarkersPage;
答案1
得分: 1
你需要在你的 dataChanges 中调用 setData(data…),而不是 return data…。
此外,我建议你使用 Redux Toolkit 中的 createSelector,这样你可以像这样做:
const sortedData = useSelector((state) => sortedDataSelector(state, sortType))
const sortedDataSelector = createSelector(
  (state, sortType) => state.data.markers,
  (state, sortType) => sortType,   
  (markers, sortType) => { 
    if (sortType === 1)
      return markers.sort(…)
  } 
  …
)
Selectors 有点棘手,你可以从这里开始学习:https://redux.js.org/usage/deriving-data-selectors#createselector-overview
英文:
You have to call setData(data…) instead of return data… inside your dataChanges
however I can recommend using createSelector from redux toolkit so then you can do something like that:
const sortedData = useSelector((state) => sortedDataSelector(state, sortType) 
const sortedDataSelector = createSelector(
  (state, sortType) => state.data.markers,
  (state, sortType) => sortType,   
  (markers, sortType) => { 
  if (sortType === 1)
    return markers.sort(…)
  } 
  …
)
Selectors are a bit tricky you can start from here https://redux.js.org/usage/deriving-data-selectors#createselector-overview
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论