繁体   English   中英

使用反应路由器时,无法从道具访问 redux 动作

[英]Can't access redux actions from props when working with react router

我对反应和 redux 还很陌生,当与反应路由器结合使用时,我在从道具访问我的 redux 动作时遇到问题。 我已经尝试了很多格式化配置,但无论我尝试什么,道具都只有反应路由器功能,即历史、匹配和位置。 我正在使用connected-react-router,但它似乎没有做任何事情。 我已经能够从我的导航菜单组件访问 redux 操作,所以我认为那里没有任何问题。

这是我尝试的最新配置的示例:

const mapStateToProps = (state) => {
    return { isSignedIn: state.auth.isSignedIn }
}

const ConnectedApp = connect(
    mapStateToProps,
    { signOut, signIn }
)(App);

ReactDOM.render(
    <Provider store={store}>
        <ConnectedRouter basename={baseUrl} history={history}>
            <ConnectedApp />
        </ConnectedRouter>
    </Provider>,
  rootElement);

这是里面的应用程序:

class App extends Component {
    static displayName = App.name;


  render () {
    return (
        <Layout>
            <Route exact path='/' component={(props) =><Home {...props}/>} />
            <Route exact path='/LogInExisting' component={(props) => <LogInExisting {...props} />} />
            <Route exact path='/LogInCreate' component={(props) => <LogInCreate {...props} />} />
      </Layout>
    );
  }
}

这是尝试访问登录操作的内容:

const LogInExisting = (props) => {
    const history = useHistory();

    const handleSignIn = async (e) => {
        e.preventDefault()

        var data = {
            UserName: document.getElementById('login').value,
            Password: document.getElementById('password').value
        }

        var response = await fetch('LogInExistingUser', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        });

        var respData = await response.json();
        if (!respData.success) {
            //TODO: Error handling
        } else {
            props.signIn();
            history.push('/')
        }
    }

我觉得我错过了一些明显的东西,但我真的可以使用一些帮助。

当使用Route组件的component prop function 时,您正在传递路径prop( historylocationmatch )。

<Route
  exact
  path='/LogInExisting'
  component={(props) => <LogInExisting {...props} />}
/>

缺少的是传递给App的道具的传递。

<Route
  exact
  path='/LogInExisting'
  component={(routeProps) => <LogInExisting {...routeProps} {...this.props} />}
/>

您不想在component道具上使用匿名 function ,因为这将在每次App呈现时重新安装路由组件。 相反,使用render道具 function,它适用于这个用例。 有关更深入的解释,请参阅 路由渲染方法

<Route
  exact
  path='/LogInExisting'
  render={(routeProps) => <LogInExisting {...routeProps} {...this.props} />}
/>

话虽如此,您使用的是 Redux,它是使用React Context API 构建的,它解决了“道具钻孔”的问题。 你不应该通过你的 redux state 和像这样的道具来行动。 将路由组件包装在本地connect HOC 中。

<Route exact path='/LogInExisting' component={LogInExisting} />

登录现有

const mapStateToProps = (state) => ({
  isSignedIn: state.auth.isSignedIn,
});

const mapDispatchToProps = { signOut, signIn };

export default connect(mapStateToProps, mapDispatchToProps)(LogInExisting);

由于LogInExisting是一个 function 组件,因此您可以使用useDispatchuseSelector挂钩来代替connect HOC。

import { useDispatch, useSelector } from 'react-redux';
import { signIn } from '../path/to/actions';

const LogInExisting = (props) => {
  const dispatch = useDispatch();
  const isSignedIn = useSelector(state => state.auth.isSignedIn);

  const history = useHistory();

  const handleSignIn = async (e) => {
    e.preventDefault();

    ...

    if (!respData.success) {
      //TODO: Error handling
    } else {
      dispatch(signIn());
      history.push('/');
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM