I learn react JavaScript and now I have a question about React Redux .
I have a component that listen to a Redux store value that is galled newTag
Here is the Component:
/*
* Component handles creating new Tags
*/
class AddTag extends React.Component {
constructor(props) {
super(props);
this.state = {
tagName: '',
categoryName: '',
};
}
submit = () => {
const { tagName, categoryName } = this.state;
const { tagsTag, tagsCategories } = this.props;
// Test if the tag is already created
const result = tagsTag.find(tag => tag.name === tagName);
if (result) {
if (result.category.name === categoryName.name) console.log('jj');
}
const { saveTag } = this.props;
saveTag(tagName.trim(), categoryName);
};
changeCategoryName = categoryName => {
this.setState({
categoryName,
});
};
changeTagName = tagName => {
this.setState({
tagName,
});
};
render() {
const { classes, tagsCategories, isSavingNewTagStarted, newTagErrMsg, newTag } = this.props;
const { tagName, categoryName } = this.state;
return (
<Container className={classes.root}>
<Typography className={classes.typography} gutterBottom variant="h6" align="left">
Type the new Tag name and select the Tag category
</Typography>
<div>
<TextField
className={classes.tagTextField}
id="outlined-basic"
label="New Tag Name"
placeholder="New Tag Name"
variant="outlined"
value={tagName}
onChange={e => this.changeTagName(e.target.value)}
autoComplete="off"
InputProps={{
className: classes.inputBackground,
}}
InputLabelProps={{
className: classes.inputLabel,
}}
/>
<FormControl>
<InputLabel id="category-select">Category</InputLabel>
<Select
className={classes.selectInput}
labelId="category-select"
id="demo-simple-select-helper"
value={categoryName}
onChange={e => this.changeCategoryName(e.target.value)}
>
{tagsCategories &&
tagsCategories.map((element, index) => {
return element.name !== 'All Tags' ? (
<MenuItem value={element} key={element.id}>
{element.name}
</MenuItem>
) : null;
})}
</Select>
</FormControl>
<Button
className={classes.button}
onClick={() => this.submit()}
variant="contained"
color="primary"
disabled={!tagName || !categoryName}
>
Save Tag
</Button>
{newTagErrMsg && <p className="error">{newTagErrMsg.message}</p>}
{newTag && <p>New Tag was saved!</p>}
</div>
<div>{isSavingNewTagStarted ? <Dots /> : null}</div>
</Container>
);
}
}
const mapDispatchToProps = dispatch => ({
saveTag: (name, category) => dispatch(saveNewTag(name, category)),
});
const mapStateToProps = state => {
return {
tagsCategories: state.global.tagsCategories,
tagsTag: state.global.tags,
isSavingNewTagStarted: state.global.isSavingNewTagStarted,
newTagErrMsg: state.global.newTagErrMsg,
newTag: state.global.newTag,
};
};
const enhance = compose(withStyles(styles), connect(mapStateToProps, mapDispatchToProps));
export default enhance(AddTag);
When a new Tag is saved this code line is true:
{newTag && <p>New Tag was saved!</p>}
problem is that the newTag
from Redux store is after the new tag is saved, always true. So this means that the text "New Tag was saved" is then always visible.
I wonder about a way to reset the Redux store newTag
so the text "New Tag was saved" is not showed after some render later.
newTag
like 'nothing' (it is not used anywhere else)localstorage
variable to use and test for if newTag
is same as before then the "New Tag was saved" will not be showed.Is there some Redux way method I have missed maybe?
Here is the reduces following well known praxis I think.
import { globalActionTypes } from './global.types';
const INIT_STATE = {
tags: [],
tagsCategories: [],
isSavingNewTagStarted: false,
newTag: '',
newTagErrMsg: '',
};
const globalReducer = (state = INIT_STATE, action) => {
switch (action.type) {
// SET_TAGS_ADDED
case globalActionTypes.SET_TAGS:
return {
...state,
tags: action.payload,
};
// SET_TAGS_CATEGORIES
case globalActionTypes.SET_TAGS_CATEGORIES:
return {
...state,
tagsCategories: action.payload,
};
// ADD_NEW_TAG
case globalActionTypes.ADD_NEW_TAG_START:
return {
...state,
isSavingNewTagStarted: true,
};
case globalActionTypes.ADD_NEW_TAG_SUCCESS:
return {
...state,
isSavingNewTagStarted: false,
newTag: action.payload,
};
case globalActionTypes.ADD_NEW_TAG_FAILURE:
return {
...state,
isSavingNewTagStarted: false,
newTagErrMsg: action.payload,
};
default:
return state;
}
};
export default globalReducer;
Just dispatch an action to clear newTag
. No need to ruminate over it.
As of good practices, will not recommend changing the redux store for the manipulation of UI of the app. Redux should store data to be displayed.
Solution for the above case can be done in the following way:
In this way, we are not changing anything in redux and are also able to solve the issue by changing the code on the component level.
try to pass ...state
to the default case
default:
return {
...state
}
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.