简体   繁体   中英

React/Redux: Encapsulate mapStateToProps prop into a variable in stateless component

I have a React component that calls a Redux selector function multiple times. I'm looking to refactor by storing the function call within a variable and using that within my component. This is to avoid having to call the same function multiple times when rendering a component versus just one time by storing it into a variable.

In my code, I am using dataLayerName to store my selector function: getDataLayerName . I notice that the value of dataLayerName is logging the function call, and not the actual value from the store.

// Code edited for brevity
const COOKIE = 'cookie';

const dataLayerName = ({ getDataLayerName }) => getDataLayerName;

const HowItWorksItem = ({
    getTranslations,
    getDataLayerName,
}) =>
        <div>
            <div>
                {getTranslations({
                    title: 'Title 1',
                    cookie: COOKIE,
                    dataLayerName,
                })}
            </div>
            <div>
                {getTranslations({
                    title: 'Title 2',
                    cookie: COOKIE,
                    dataLayerName,
                })}
            </div>
        </div>
    </Cell>;

const mapStateToProps = state => ({
    getDataLayerName: selectDataLayerName(state, COOKIE),
});

export default connect(mapStateToProps)(HowItWorksItem);

For the work that you are doing, I would recommend two files - one for selecting the data your component will need and one for rendering DOM elements based on your data. I think this will greatly clarify your code.

Also, there are some issues with the code you posted. First, your selectors should be a function of the state. Assuming getDataLayerName is a valid selector defined somewhere else, you should be able to use it in your container (the file where you get the data) like so:

HowItWorksItemContainer.js

import HowItWorksItem from './HowItWorksItem.js'
import { getDataLayerName } from './selectors.js'

function mapStateToProps(state) {
  const dataLayerName = getDataLayerName(state);
  return { dataLayerName };
}

export default connect(mapStateToProps)(HowItWorksItem);

As a side note, I personally think Redux selectors should have a standard suffix, for example I would call it dataLayerNameSelector instead of getDataLayerName . But it's completely up to you.

Next, you want to render your HowItWorksItem(s) to the DOM. I am assuming you want to render just one HowItWorksItem with two titles (as in the code you posted). If you want two HowItWorksItems , you would create two HowItWorksItemContainers in a parent component, like so: <HowItWorksItemContainer title='Title 1' /> .

There is also an issue with your DOM: there is a closing </Cell> tag but no opening tag. For now I just omitted it, but you could also just add an opening <Cell> instead.

import React from 'react';
import getTranslations from './utilities';

const COOKIE = 'cookie';

function HowItWorksItem(props) {
  return (
    <div>
        <div>
            {getTranslations({
                title: 'Title 1',
                cookie: COOKIE,
                props.dataLayerName,
            })}
        </div>
        <div>
            {getTranslations({
                title: 'Title 2',
                cookie: COOKIE,
                props.dataLayerName,
            })}
        </div>
    </div>
  );
}

Hopefully this answer gives you some clarity about using Redux selectors to pass data to your components.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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