Reputation: 907
So I have a search bar where I store the queries with redux, which seems to work. I am now trying to access that query in a results component which I am going to use to display the results of the query.
I have tried using MapStateToProps and then just calling {this.props.query} in my Results component, but that doesn't get the query changes from the search bar.
Store creation:
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();
Search:
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)
);
Search-results:
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)
Search-reducer:
export const initialQuery = '';
export const searchReducer = (state = initialQuery, action) => {
switch (action.type) {
case "SEARCH":
return action.value;
default:
return state;
}
};
In search-results, {this.props.query} is always undefined, even though I can see the state.query changing when I input text in the search bar. I am assuming I am misunderstanding something about Redux, but I'm not super sure what, since I am able to update the searchQuery properly in my "Search" component.
Upvotes: 2
Views: 217
Reputation: 2309
Use :
function mapStateToProps(state) {
return { query: state.query.searchQuery };
}
Upvotes: 1
Reputation: 6529
It looks like you're mixing up query
and searchQuery
in a few places.
combineReducers({
user: userReducer,
query: searchReducer,
}),
You're setting state.query
as your global query object, but both of your mapStateToProps
are trying to access state.searchQuery
.
Also, in Search
's render, you have const {searchQuery, classes} = this.props;
, but again, mapStateToProps
is mapping state.searchQuery
to props.query
, so props.searchQuery
is undefined.
Seems like you just have to make sure you're using the correct mapping, or pick either query
or searchQuery
and use it both in global state and in props.
Upvotes: 3