/keywordsActions
import { UPDATE_KEYWORDS } from "./actionTypes";
import queryString from "query-string";
const keywordsArrayFromUrl = () => {
const query = queryString.parse(window.location.search);
if (query.keywords) {
const removeDuplicate = new Set(query.keywords.split(" "));
return Array.from(removeDuplicate);
}
return [];
};
export function updateKeywords() {
return async dispatch => {
dispatch({
type: UPDATE_KEYWORDS,
payload: await keywordsArrayFromUrl()
});
};
}
/keywordReducer
import { UPDATE_KEYWORDS } from "../actions/actionTypes";
export default function(state = [], action) {
switch (action.type) {
case UPDATE_KEYWORDS:
return action.payload;
default:
return state;
}
}
/SearchBar -- React Component
import React, { Component } from "react";
import { withRouter } from "react-router-dom";
//Redux
import { connect } from "react-redux";
import { updateKeywords } from "../store/actions/KeywordsAction";
class Searchbar extends Component {
constructor(props) {
super(props);
this.state = {
keywords : this.props.keywords
keywordsString: this.props.keywords.join(" ")
};
}
componentDidMount() {
this.props.updateKeywords();
console.log(this.props)
setTimeout(() => console.log(this.props), 10);
}
_handleChange = e => {
this.setState({ keywordsString: e.target.value });
};
_handleSearch = value => {
this.setState({ keywordsString: value });
this.props.history.push(`/search?keywords=${value}`);
};
render() {
return (
<Search
className="Searchbar"
placeholder="Cauta prin iBac..."
value={this.state.keywordsString}
onChange={this._handleChange}
onSearch={this._handleSearch}
/>
);
}
}
const mapStateToProps = state => {
return {
keywords: state.keywords
};
};
export default connect(
mapStateToProps,
{ updateKeywords }
)(withRouter(Searchbar));
I want to save the keywords from the Url to the store and then pass it to the Search bar state.
But i dont understand this :
componentDidMount() {
this.props.updateKeywords();
console.log(this.props); // this.props.keywords is empty
setTimeout(() => console.log(this.props), 10); // After 10 ms this.props.keywords is no empty
}
After 10 ms the props of Searchbar gets updated but the component doesn't render again.
Sorry for my question, I am really new to React / Redux. Please let me know what I am doing wrong. Thank you all!
Update :
componentDidMount() {
this.props.updateKeywords();
setTimeout(() => {
this.setState({
keywordsString: this.props.keywords.join(" ")
});
}, 0);
}
This code is also working... but this other is not working
componentDidMount() {
this.props.updateKeywords();
this.setState({
keywordsString: this.props.keywords.join(" ")
});
}
The reason is that
componentDidMount
is only called once on mount. What you're looking for is eithercomponentShouldUpdate
orcomponentDidUpdate
or therender
function, all of which are called when your component receives the updated state from redux. You can read here for more information on what these functions do.https://reactjs.org/docs/react-component.html#updating