如何将 React.memo 与 react-redux connect 一起使用?
How to use React.memo with react-redux connect?
有人知道在使用 react-redux 的 connect
函数时如何用 React.memo
包装 React 组件吗?
例如,您将如何修改以下内容?
let Button = (props: Props) => (
<button onClick={props.click}>{props.value}</button>
);
Button = connect(
mapStateToProps,
mapDispatchToProps
)(Button);
我试过:
let Button = React.memo((props: Props) => (
<button onClick={props.click}>{props.value}</button>
));
Button = connect(
mapStateToProps,
mapDispatchToProps
)(Button);
但是,connect
返回的函数需要传递一个组件,因此它会出错:
Uncaught Error: You must pass a component to the function returned by
connect. Instead received {"compare":null}
Codesandbox demo
正如错误信息所说,你需要将一个组件传递给从connect
返回的函数。
(这意味着[=中的第二对() 13=] )
作为 React.Memo
returns 组件,将其传递到 connect
的第二个函数中。
这是您可以执行此操作的方法。
export const MemoizedDemoComponent = connect(mapStateToProps)(React.memo(DemoComponent);
演示组件:
import React from "react";
import { connect } from "react-redux";
const DemoComponent = props => (
<div>
<p>My demo component fueled by: {props.fuel}!</p>
<p>Redux: {props.state}</p>
</div>
);
const mapStateToProps = state => ({
state: "your redux state..."
});
// create a version that only renders on prop changes
export const MemoizedDemoComponent = connect(mapStateToProps)(
React.memo(DemoComponent)
);
对于工作示例,还要检查 codesandbox。
React.memo
只是一个 HOC,所以你可以使用:
无备注:
connect(
mapStateToProps,
mapDispatchToProps
)(Button);
附备注:
connect(
mapStateToProps,
mapDispatchToProps
)(React.memo(Button));
甚至包装连接:(这应该是连接的解决方案)
React.memo(
connect(
mapStateToProps,
mapDispatchToProps
)(Button)
);
就像我们对 withRouter
所做的那样:withRouter(connect(...)())
您的解决方案应该可行(我没有尝试那样复制粘贴),但您还必须将 react-redux
更新到最新版本。
顺便说一句,我认为 React.memo
在许多 HOC 中的正确实现应该是最接近组件本身的:React.memo
的目标是检查所有新的道具是否组件接收到的与最后一个道具相同。如果任何 HOC 转换或向组件添加任何道具 - connect
通过将 Redux 存储映射到道具来完成,React.memo
应该知道它以便决定是否更新组件。
所以我会去做类似的事情:
//import what you need to import
const Component = props => <div>{/* do what you need to do here */}</div>
export default compose(
connect(mapStateToProps, dispatchToProps),
/* any other HOC*/
React.memo
)(Component);
同样的问题。通过将 react-redux
升级到版本 5.1.0 修复。
对于想知道为什么 react-redux
抛出此错误的人。
对我来说,我使用了版本 5.0.7
,react-redux/src/components/connectAdvanced.js
行:92
invariant(
typeof WrappedComponent == 'function',
`You must pass a component to the function returned by ` +
`${methodName}. Instead received ${JSON.stringify(WrappedComponent)}`
);
升级后此代码更改为:
invariant(
isValidElementType(WrappedComponent),
`You must pass a component to the function returned by ` +
`${methodName}. Instead received ${JSON.stringify(WrappedComponent)}`
);
如何检查 WrappedComponent
更改为由 react-is
公开的 isValidElementType(WrappedComponent)
所以,yarn 更新 react-redux
至少到@Maxime Chéramy 提到的版本
有人知道在使用 react-redux 的 connect
函数时如何用 React.memo
包装 React 组件吗?
例如,您将如何修改以下内容?
let Button = (props: Props) => (
<button onClick={props.click}>{props.value}</button>
);
Button = connect(
mapStateToProps,
mapDispatchToProps
)(Button);
我试过:
let Button = React.memo((props: Props) => (
<button onClick={props.click}>{props.value}</button>
));
Button = connect(
mapStateToProps,
mapDispatchToProps
)(Button);
但是,connect
返回的函数需要传递一个组件,因此它会出错:
Uncaught Error: You must pass a component to the function returned by connect. Instead received {"compare":null}
Codesandbox demo
正如错误信息所说,你需要将一个组件传递给从connect
返回的函数。
(这意味着[=中的第二对() 13=] )
作为 React.Memo
returns 组件,将其传递到 connect
的第二个函数中。
这是您可以执行此操作的方法。
export const MemoizedDemoComponent = connect(mapStateToProps)(React.memo(DemoComponent);
演示组件:
import React from "react";
import { connect } from "react-redux";
const DemoComponent = props => (
<div>
<p>My demo component fueled by: {props.fuel}!</p>
<p>Redux: {props.state}</p>
</div>
);
const mapStateToProps = state => ({
state: "your redux state..."
});
// create a version that only renders on prop changes
export const MemoizedDemoComponent = connect(mapStateToProps)(
React.memo(DemoComponent)
);
对于工作示例,还要检查 codesandbox。
React.memo
只是一个 HOC,所以你可以使用:
无备注:
connect(
mapStateToProps,
mapDispatchToProps
)(Button);
附备注:
connect(
mapStateToProps,
mapDispatchToProps
)(React.memo(Button));
甚至包装连接:(这应该是连接的解决方案)
React.memo(
connect(
mapStateToProps,
mapDispatchToProps
)(Button)
);
就像我们对 withRouter
所做的那样:withRouter(connect(...)())
您的解决方案应该可行(我没有尝试那样复制粘贴),但您还必须将 react-redux
更新到最新版本。
顺便说一句,我认为 React.memo
在许多 HOC 中的正确实现应该是最接近组件本身的:React.memo
的目标是检查所有新的道具是否组件接收到的与最后一个道具相同。如果任何 HOC 转换或向组件添加任何道具 - connect
通过将 Redux 存储映射到道具来完成,React.memo
应该知道它以便决定是否更新组件。
所以我会去做类似的事情:
//import what you need to import
const Component = props => <div>{/* do what you need to do here */}</div>
export default compose(
connect(mapStateToProps, dispatchToProps),
/* any other HOC*/
React.memo
)(Component);
同样的问题。通过将 react-redux
升级到版本 5.1.0 修复。
对于想知道为什么 react-redux
抛出此错误的人。
对我来说,我使用了版本 5.0.7
,react-redux/src/components/connectAdvanced.js
行:92
invariant(
typeof WrappedComponent == 'function',
`You must pass a component to the function returned by ` +
`${methodName}. Instead received ${JSON.stringify(WrappedComponent)}`
);
升级后此代码更改为:
invariant(
isValidElementType(WrappedComponent),
`You must pass a component to the function returned by ` +
`${methodName}. Instead received ${JSON.stringify(WrappedComponent)}`
);
如何检查 WrappedComponent
更改为由 react-is
isValidElementType(WrappedComponent)
所以,yarn 更新 react-redux
至少到@Maxime Chéramy 提到的版本