Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我可以使用useSelector()返回更深层次的嵌套属性/状态值吗?_Javascript_Reactjs_Redux_React Redux - Fatal编程技术网

Javascript 我可以使用useSelector()返回更深层次的嵌套属性/状态值吗?

Javascript 我可以使用useSelector()返回更深层次的嵌套属性/状态值吗?,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,来自react redux官方: 调度操作时,useSelector()将对以前的选择器结果值和当前结果值进行引用比较。如果它们不同,组件将被迫重新渲染。如果它们相同,组件将不会重新渲染 如果我这样做: 重复使用状态 state = { groupAB: { propA: valueA, propB: valueB }, propC, // ETC } SomeComponent.tsx const propA = useSelector((state) =&

来自react redux官方:

调度操作时,useSelector()将对以前的选择器结果值和当前结果值进行引用比较。如果它们不同,组件将被迫重新渲染。如果它们相同,组件将不会重新渲染

如果我这样做:

重复使用状态

state = {
  groupAB: {
    propA: valueA,
    propB: valueB
  },
  propC,
  // ETC
}
SomeComponent.tsx

const propA = useSelector((state) => state.groupAB.propA);
如果
groupAB
对象更改了其引用(因为
propB
发生了变化),但
propA:valueA
保持不变,该组件将如何工作

我所期望的是:

即使
groupAB
更改,组件也不应重新呈现,因为
useSelector()
关心的是返回,在本例中,返回值是
valueA
。我说得对吗?

在我们有:

当函数组件呈现时,将调用提供的选择器函数,其结果将从useSelector()钩子返回。(如果缓存结果与组件上一次呈现的函数引用相同,则钩子可能会返回缓存结果,而无需重新运行选择器。)

您将使用arrow函数作为选择器函数,因此每个渲染中的引用永远不会相同,它也永远不会从缓存中读取结果

顺便说一下,我们还有:

将操作分派到Redux存储时,只有当选择器结果与上次结果不同时,useSelector()才会强制重新渲染

因为从选择器函数返回的值是一个原始的,它是一个简单的字符串,不被识别为对象的一部分或与对象相关的东西(我认为是你关心的)-正如你所说的,在这个场景中它没有改变,它会考虑与前一个相同,并且不会强制重新渲染组件

因此,在最后,每次重新渲染组件时都会触发函数,但更改存储区中不会导致更改所述原语值的部分不会以重新渲染组件结束。

刚刚测试过,工作正常

如果返回值不变,组件将不会重新渲染。即使它是一个深嵌套的值,如示例
state.groupAB.propA=“valueA”

当然,要测试此行为,必须将其包装在
React.memo()
中,否则无论何时父对象重新渲染,它都将重新渲染


App.js

import React from "react";
import "./styles.css";
import { useDispatch, useSelector } from "react-redux";
import SomeComponent from "./SomeComponent";

export default function App() {
  console.log("App rendering...");

  const state = useSelector((state) => state);
  const dispatch = useDispatch();

  function updateState() {
    dispatch({ type: "UPLOAD_GROUP_AB_AND_PROP_B" });
  }

  return (
    <div>
      <div>State: {JSON.stringify(state)}</div>
      <button onClick={updateState}>Update state</button>
      <SomeComponent />
    </div>
  );
}

const initialState = {
  groupAB: {
    propA: "valueA",
    propB: "valueB"
  },
  propC: "valueC"
};

export const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "UPLOAD_GROUP_AB_AND_PROP_B": {
      return {
        // WILL CREATE A NEW STATE OBJ
        ...state,
        groupAB: {
          // WILL CREATE A NEW groupAB OBJ
          ...state.groupAB, // propA WILL REMAIN THE SAME
          propB: "newValueB" // WILL UPDATE propB VALUE
        }
      };
    }
    default: {
      return state;
    }
  }
};

import React from "react";
const { useSelector } = require("react-redux");

function SomeComponent() {
  console.log("SomeComponent rendering...");

  const propA = useSelector((state) => state.groupAB.propA);

  return (
    <div>
      <hr />
      <div>This is SomeComponent</div>
      state.groupAB.propA: {propA}
    </div>
  );
}

export default React.memo(SomeComponent);

import React from "react";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import { Provider } from "react-redux";

import App from "./App";
import { reducer } from "./reducer";

const store = createStore(reducer);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);
SomeComponent.js

import React from "react";
import "./styles.css";
import { useDispatch, useSelector } from "react-redux";
import SomeComponent from "./SomeComponent";

export default function App() {
  console.log("App rendering...");

  const state = useSelector((state) => state);
  const dispatch = useDispatch();

  function updateState() {
    dispatch({ type: "UPLOAD_GROUP_AB_AND_PROP_B" });
  }

  return (
    <div>
      <div>State: {JSON.stringify(state)}</div>
      <button onClick={updateState}>Update state</button>
      <SomeComponent />
    </div>
  );
}

const initialState = {
  groupAB: {
    propA: "valueA",
    propB: "valueB"
  },
  propC: "valueC"
};

export const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "UPLOAD_GROUP_AB_AND_PROP_B": {
      return {
        // WILL CREATE A NEW STATE OBJ
        ...state,
        groupAB: {
          // WILL CREATE A NEW groupAB OBJ
          ...state.groupAB, // propA WILL REMAIN THE SAME
          propB: "newValueB" // WILL UPDATE propB VALUE
        }
      };
    }
    default: {
      return state;
    }
  }
};

import React from "react";
const { useSelector } = require("react-redux");

function SomeComponent() {
  console.log("SomeComponent rendering...");

  const propA = useSelector((state) => state.groupAB.propA);

  return (
    <div>
      <hr />
      <div>This is SomeComponent</div>
      state.groupAB.propA: {propA}
    </div>
  );
}

export default React.memo(SomeComponent);

import React from "react";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import { Provider } from "react-redux";

import App from "./App";
import { reducer } from "./reducer";

const store = createStore(reducer);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);
从“React”导入React;
const{useSelector}=require(“react redux”);
函数SomeComponent(){
log(“SomeComponent呈现…”);
const-propA=useSelector((state)=>state.groupAB.propA);
返回(

这是某个组件 state.groupAB.propA:{propA} ); } 导出默认的React.memo(SomeComponent);
index.js

import React from "react";
import "./styles.css";
import { useDispatch, useSelector } from "react-redux";
import SomeComponent from "./SomeComponent";

export default function App() {
  console.log("App rendering...");

  const state = useSelector((state) => state);
  const dispatch = useDispatch();

  function updateState() {
    dispatch({ type: "UPLOAD_GROUP_AB_AND_PROP_B" });
  }

  return (
    <div>
      <div>State: {JSON.stringify(state)}</div>
      <button onClick={updateState}>Update state</button>
      <SomeComponent />
    </div>
  );
}

const initialState = {
  groupAB: {
    propA: "valueA",
    propB: "valueB"
  },
  propC: "valueC"
};

export const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "UPLOAD_GROUP_AB_AND_PROP_B": {
      return {
        // WILL CREATE A NEW STATE OBJ
        ...state,
        groupAB: {
          // WILL CREATE A NEW groupAB OBJ
          ...state.groupAB, // propA WILL REMAIN THE SAME
          propB: "newValueB" // WILL UPDATE propB VALUE
        }
      };
    }
    default: {
      return state;
    }
  }
};

import React from "react";
const { useSelector } = require("react-redux");

function SomeComponent() {
  console.log("SomeComponent rendering...");

  const propA = useSelector((state) => state.groupAB.propA);

  return (
    <div>
      <hr />
      <div>This is SomeComponent</div>
      state.groupAB.propA: {propA}
    </div>
  );
}

export default React.memo(SomeComponent);

import React from "react";
import ReactDOM from "react-dom";
import { createStore } from "redux";
import { Provider } from "react-redux";

import App from "./App";
import { reducer } from "./reducer";

const store = createStore(reducer);

const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);
从“React”导入React;
从“react dom”导入react dom;
从“redux”导入{createStore};
从“react redux”导入{Provider};
从“/App”导入应用程序;
从“/reducer”导入{reducer}”;
const store=createStore(reducer);
const rootElement=document.getElementById(“根”);
ReactDOM.render(
,
根元素
);