如何访问不同组件中的商店?

How to access store in different component?

所以我有一个搜索栏,我用 redux 存储查询,这似乎有效。我现在正尝试在我将用于显示查询结果的结果组件中访问该查询。

我试过使用 MapStateToProps,然后在我的结果组件中调用 {this.props.query},但这并没有从搜索栏中获取查询更改。

创建商店:

import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { BrowserRouter } from "react-router-dom";
import { createStore, combineReducers, applyMiddleware } from "redux";
import { userReducer } from "./redux/reducers/user-reducer";
import { searchReduer } from "./redux/reducers/search-reducer"
import logger from "redux-logger";
import { Provider } from "react-redux";

const store = createStore(
  combineReducers({
      user: userReducer,
      query: searchReducer,
  }),
  {},
  applyMiddleware(logger)
);

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

serviceWorker.unregister();

搜索:

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';
import { connect } from "react-redux";
import elasticsearchUtility from "../utilities/elastic-search-utility";

const styles = theme => ({
    container: {
        display: 'flex',
        flexWrap: 'wrap',
        justifyContent: 'center',
        flexDirection: 'row',
    },
    margin: {
        margin: theme.spacing.unit,
    },
    cssLabel: {
        color: 'white',
        '&$cssFocused': {
            color: 'white',
        },
    },
    cssFocused: {
    },
    cssUnderline: {
        color: 'white',
    },
    cssOutlinedInput: {
        '&$cssFocused $notchedOutline': {
            borderColor: 'white',
        },
    },
    notchedOutline: {
        borderWidth: '1px',
        borderColor: 'white !important'
    },
});

class Search extends Component{
    state = {
        searchQuery: ""
    };

    componentDidMount() {
        elasticsearchUtility.startClient();
    }

    onChange = event => {
        this.props.updateQuery(event.target.value);
    };

    render() {
        const {searchQuery, classes} = this.props;

        return (
            <div className={this.props.classes.container}>
                <TextField
                    fullWidth={true}
                    className={classes.margin}
                    InputLabelProps={{
                        classes: {
                            root: classes.cssLabel,
                            focused: classes.cssFocused,
                        },
                    }}
                    InputProps={{
                        classes: {
                            root: classes.cssOutlinedInput,
                            focused: classes.cssFocused,
                            notchedOutline: classes.notchedOutline,
                        },
                    }}
                    onChange={this.onChange}
                    label="Service search"
                    variant="outlined"
                    id="custom-css-outlined-input"
                    value={searchQuery}
                />
            </div>
        );
    }
}
const mapStateToProps = (state) => {
    return {
        query: state.searchQuery
    }
};

const mapDispatchToProps = (dispatch) => {
    return {
        updateQuery: (query) => {
            dispatch(search(query))
        }
    }
};

function search(value) {
    return {type: "SEARCH", value};
}

Search.propTypes = {
    classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(
    connect(
        mapStateToProps,
        mapDispatchToProps
    )(Search)
);

搜索结果:

import React, {Component} from 'react';
import connect from "react-redux/es/connect/connect";

class SearchResults extends Component {

    render() {
        console.log(this.props.query);
        return (
            <div>
            <h1>Test + {this.props.query}</h1>
            </div>
        );
    }
}

function mapStateToProps(state) {
    return { query: state.searchQuery };
}

export default connect(mapStateToProps)(SearchResults)

搜索缩减器:

export const initialQuery = '';

export const searchReducer = (state = initialQuery, action) => {

    switch (action.type) {
        case "SEARCH":
            return action.value;
        default:
            return state;
    }

};

在搜索结果中,{this.props.query} 始终未定义,即使我在搜索栏中输入文本时可以看到 state.query 发生变化。我假设我对 Redux 有一些误解,但我不太确定是什么,因为我能够在我的 "Search" 组件中正确更新 searchQuery。

您似乎在一些地方混淆了 querysearchQuery

  combineReducers({
      user: userReducer,
      query: searchReducer,
  }),

您正在将 state.query 设置为您的全局查询对象,但是您的两个 mapStateToProps 都在尝试访问 state.searchQuery.

此外,在 Search 的渲染中,您有 const {searchQuery, classes} = this.props;,但同样,mapStateToProps 正在将 state.searchQuery 映射到 props.query,因此 props.searchQuery 未定义。

看来您只需要确保使用正确的映射,或者选择 querysearchQuery 并在全局状态和道具中使用它。

使用:

function mapStateToProps(state) {
return { query: state.query.searchQuery };
}