问题描述
我目前正在进行freeCodeCamp React挑战构建食谱框一个>.我必须满足使用HTML5网络存储来保存用户所做的更改的用户故事,以便即使刷新页面也能保留更改.但是我没有事先计划就构建了我的React Application ,现在我陷入了困境我不知道如何在我的应用程序中添加此功能.
I'm currently doing the freeCodeCamp React challenge Building a Recipe Box.I have to fulfil the User Story of using HTML5 web storage to save changes made by the user so that even when the page is refreshed the changes remain. However I built my React Application without planning this beforehand , and now I'm stuck in a situation where I don't know how to add this functionality to my app.
P.S我尝试使用全局变量和设置状态以及设置本地存储.我是React的新手.
P.S I tried using global variables and setting state along with setting local storage . I'm new to React.
/*-------------------------------------------------------------------------*/
var RecipeEdit = React.createClass({
getInitialState: function() {
return {
titleOne: 'Sakkarai Pongal Recipe (Sweet Pongal Recipe)',
urlOne: 'https://4.bp.blogspot.com/-a1NWFkB9xLU/U1Er4eD_vlI/AAAAAAAAd-w/tUECZ8OUCKw/s1600/sakkarai+pongal+recipe.jpg',
contentOne: 'Ingredients: Raw rice - 1 cup,Mung bean - 2 to 4 tbsp,Jaggery - 1 cup,Clarified butter - 1/4 cup (can adjust as per preference),Cardamom - 1,Water for cooking rice - 6 cups,Milk - 2 tbsp,Water for jaggery syrup - 1/2 cup,Edible camphor - mustard seed size,Clove - 1,Nutmeg powder- a pinch ,Salt - a pinch (optional),Cashews, raisins - 1 tbsp each',
titleTwo: 'Medhu Vadai / Ulundu Vadai Recipe',
urlTwo: 'https://3.bp.blogspot.com/-7qyx9n0Wyxo/UKC3ECH8QGI/AAAAAAAAbs4/WN-0u5cVUxU/s1600/Ulundhu-vadai--Medhu-vadai.jpg',
contentTwo: 'Ingredients: Black lentil - 3/4 cup,Small onion, shallots(or Big onion – 1) - 10 ,Green pimento pepper - 2 ,Ginger - 1 inch piece,Coriander leaves - 2 tblp, chopped.,Curry leaves - A sprig,Asafoetida - 3-4 pinches,Salt - As needed,Water - As needed',
titleThree: 'Neer Mor (Recipe For Spiced Buttermilk)',
urlThree: 'http://farm9.staticflickr.com/8244/8638427263_fc66ac04a3_z.jpg',
contentThree: 'Ingredients: Plain yogurt - 1 cup,Water - 4 cups,Green pimento pepper - 2,Chopped ginger - 1 tblsp,Chopped cilantro - 1 tblsp,Chopped curry leaves - 1 sprig,Salt - As needed,Asafoetida - 1 pinch,Lemon(optional) - 1/2'
};
//localStorage.setItem('Furball_Default', //JSON.stringify(this.state));
},
/* componentWillMount: function() {
var PreviousData = JSON.parse(localStorage.getItem('Furball_Default'));
if (PreviousData) {
this.setState({
[this.state]: PreviousData
});
}
},*/
handleTitle1Change: function(event) {
this.setState({
titleOne: event.target.value
});
// localStorage.setItem('Furball_Default', //JSON.stringify(this.state));
},
handleTitle2Change: function(event) {
this.setState({
titleTwo: event.target.value
});
// localStorage.setItem('Furball_Default', //JSON.stringify(this.state));
},
handleTitle3Change: function(event) {
this.setState({
titleThree: event.target.value
});
// localStorage.setItem('Furball_Default', //JSON.stringify(this.state));
},
handleUrl1Change: function(event) {
this.setState({
urlOne: event.target.value
});
//localStorage.setItem('Furball_Default', //JSON.stringify(this.state));
},
handleUrl2Change: function(event) {
this.setState({
urlTwo: event.target.value
})
},
handleUrl3Change: function(event) {
this.setState({
urlThree: event.target.value
});
//localStorage.setItem('Furball_Default', //JSON.stringify(this.state));
},
handleContent1Change: function(event) {
this.setState({
contentOne: event.target.value
});
// localStorage.setItem('Furball_Default', //JSON.stringify(this.state));
},
handleContent2Change: function(event) {
this.setState({
contentTwo: event.target.value
});
// localStorage.setItem('Furball_Default', //JSON.stringify(this.state));
},
handleContent3Change: function(event) {
this.setState({
contentThree: event.target.value
});
//localStorage.setItem('Furball_Default', //JSON.stringify(this.state));
},
render: function() {
return (<section>
<div className="card small horizontal pink lighten-4 z-depth-4">
<div className="card-image waves-effect waves-block waves-light">
<img className="activator" src={this.state.urlOne} />
</div>
<div className="card-content">
<span className="card-title activator grey-text text-darken-4">{this.state.titleOne}</span>
</div><a className="waves-effect waves-light btn red z-depth-5 del">Delete <span className="fa fa-trash-o fa-lg"> </span></a>
<div className="card-reveal">
<span className="card-title"><i className="material-icons right">close</i></span> <div className="input-field inline">
<input type="text" onChange={this.handleTitle1Change} value={this.state.titleOne} />
<label htmlFor="title">Title</label>
</div> <div className="input-field inline">
<input type="text" onChange={this.handleUrl1Change} value={this.state.urlOne} />
<label htmlFor="url">Image URL</label>
</div><div className="input-field">
<textarea type="text" className="materialize-textarea" onChange={this.handleContent1Change} value={this.state.contentOne} /> <label>Ingredients/Directions </label> </div>
</div>
</div>
<div className="card small horizontal brown lighten- z-depth-4">
<div className="card-image waves-effect waves-block waves-light">
<img className="activator" src={this.state.urlTwo} />
</div>
<div className="card-content">
<span className="card-title activator grey-text text-darken-4">{this.state.titleTwo}</span>
</div>
<a className="waves-effect waves-light btn red z-depth-5 del">Delete <span className="fa fa-trash-o fa-lg"> </span></a>
<div className="card-reveal">
<span className="card-title"><i className="material-icons right">close</i></span> <div className="input-field inline">
<input type="text" onChange={this.handleTitle2Change} value={this.state.titleTwo} />
<label htmlFor="title">Title</label>
</div> <div className="input-field inline">
<input type="text" onChange={this.handleUrl2Change} value={this.state.urlTwo} />
<label htmlFor="url">Image URL</label>
</div><div className="input-field">
<textarea onChange={this.handleContent2Change} type="text" className="materialize-textarea" value={this.state.contentTwo} /> <label>Ingredients/Directions </label> </div>
</div>
</div>
<div className="card small horizontal lime z-depth-4">
<div className="card-image waves-effect waves-block waves-light">
<img className="activator" src={this.state.urlThree} />
</div>
<div className="card-content">
<span className="card-title activator grey-text text-darken-4">{this.state.titleThree}</span>
</div><a className="waves-effect waves-light btn red z-depth-5 del">Delete <span className="fa fa-trash-o fa-lg"> </span></a>
<div className="card-reveal">
<span className="card-title"><i className="material-icons right">close</i></span> <div className="input-field inline">
<input type="text" onChange={this.handleTitle3Change} value={this.state.titleThree} />
<label htmlFor="title">Title</label>
</div> <div className="input-field inline">
<input type="text" onChange={this.handleUrl3Change} value={this.state.urlThree} />
<label htmlFor="url">Image URL</label>
</div><div className="input-field">
<textarea onChange={this.handleContent3Change} type="text" className="materialize-textarea" value={this.state.contentThree} /> <label>Ingredients/Directions </label> </div>
</div>
</div> <Form />
</section>);
}
});
/*-------------------------------------------------------------------------*/
var Form = React.createClass({
getInitialState: function() {
return {
title: '',
url: '',
content: '',
clicked: false,
newCardArr: []
};
},
updateT: function(val) {
this.setState({
title: val.target.value
});
console.log(this.state.title);
// localStorage.setItem('Furball_New', //JSON.stringify(this.state));
},
updateU: function(val) {
this.setState({
url: val.target.value
});
console.log(this.state.url);
//localStorage.setItem('Furball_New', //JSON.stringify(this.state));
},
updateC: function(val) {
this.setState({
content: val.target.value
});
console.log(this.state.content);
// localStorage.setItem('Furball_New', //JSON.stringify(this.state));
},
onClick: function() {
this.setState({
clicked: true,
newCardArr: [<Create key={Math.random()} title={this.state.title} url={this.state.url} content={this.state.content} />, ...this.state.newCardArr]
});
},
render: function() {
return (<div> {this.state.clicked ? this.state.newCardArr : null}
<div className="center-align">
<ul className="collapsible" data-collapsible="accordion">
<li>
<div className="collapsible-header btn-floating btn-large waves-effect waves-light red z-depth-5"><i className="material-icons">edit</i> </div><h6>Add New Recipe </h6>
<div className="collapsible-body"><span><div className="input-field inline">
<input id="title" type="text" onChange={this.updateT}/>
<label className="cyan-text" htmlFor="title">Title</label>
</div> <div className="input-field inline">
<input type="text" onChange={this.updateU} />
<label className="cyan-text" htmlFor="url">Image URL</label>
</div><div className="input-field">
<textarea type="text" className="materialize-textarea" onChange={this.updateC} /> <label className="cyan-text">Ingredients/Directions </label> </div><button className="btn waves-effect waves-light z-depth-5" onClick={this.onClick} type="submit" name="action">Submit
<i className="material-icons right">send</i>
</button> </span></div>
</li>
</ul> </div> </div>)
}
});
/*-------------------------------------------------------------------------*/
var Create = React.createClass({
getInitialState: function() {
return {
title: '',
url: '',
content: ''
};
},
componentWillMount: function() {
this.setState({
title: this.props.title,
url: this.props.url,
content: this.props.content
});
/* var PreviousData = JSON.parse(localStorage.getItem('Furball_New'));
if (PreviousData) {
this.setState({
[this.state]: PreviousData
});
}*/
},
onChange: function(event) {
this.setState({
[event.target.id]: event.target.value
});
// localStorage.setItem('Furball_New', //JSON.stringify(this.state));
},
render: function() {
console.log(this.state);
return (<div className="card small horizontal z-depth-4"><div className="card-image waves-effect waves-block waves-light">
<img className="activator" src={this.state.url} />
</div> <div className="card-content">
<span className="card-title activator grey-text text-darken-4">{this.state.title}</span>
</div><a className="waves-effect waves-light btn red z-depth-5 del">Delete <span className="fa fa-trash-o fa-lg"> </span></a><div className="card-reveal">
<span className="card-title"><i className="material-icons right">close</i></span> <div className="input-field inline">
<input type="text" id="title" value={this.state.title} onChange={this.onChange} />
<label htmlFor="title">Title</label>
</div> <div className="input-field inline">
<input type="text" id="url" onChange={this.onChange} value={this.state.url} />
<label htmlFor="url">Image URL</label>
</div><div className="input-field">
<textarea type="text" className="materialize-textarea" id="content" onChange={this.onChange} value={this.state.content} /> <label>Ingredients/Directions </label> </div>
</div></div>);
}
});
/*-------------------------------------------------------------------------*/
ReactDOM.render(<RecipeEdit />, document.getElementById('app'));
/*-------------------------------------------------------------------------*/
// var recipes = [];
/*componentWillMount: function() {
var PreviousData = JSON.parse(localStorage.getItem('Furball_RecipesBox'));
if (PreviousData) {
this.setState({
[this.state]: PreviousData
});
}
},
componentDidUpdate: function(prevProps, prevState) {
localStorage.setItem('Furball_RecipesBox', JSON.stringify(this.state));
},*/
/* <div>var recipes = []; array={recipes}
<Button onClick={this.handleClick} />
var array= [this.props.array];
array.push(this.state);
</div>*/
// setTimeout(this.after, 5000);
// setTimeout( this.setState({
// clicked: true
// }),6000)
//e.preventDefault();
//console.log(this.props.array);
/* componentWillMount: function() {
var PreviousData = JSON.parse(localStorage.getItem('Furball_RecipesBox'));
if (PreviousData) {
this.setState({
[this.state]: PreviousData
});
}
},
componentWillUnmount: function() {
this.setState({
[this.props.array]: this.state
});
console.log(this.props.array);
localStorage.setItem('Furball_RecipesBox', JSON.stringify(this.props.array));
}, */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-image: url("http://cdn.backgroundhost.com/backgrounds/subtlepatterns/retina_wood.png");
}
#app {
margin: 15px;
}
.card {
border-radius: 7%;
}
.del {
margin-right: 15px;
margin-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/js/materialize.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"> </div>
推荐答案
我认为您的代码的主要问题是假设您可以在调用this.setState
之后立即访问this.state
,并且其中将包含更新后的值.
I think the main problem with your code is the assumption that you can access this.state
immediately after calling this.setState
and it will contain the updated values.
情况并非如此,这是为什么 :
This is not the case, here is why:
因此,我建议您使用第二个参数并将状态保存到其中的本地存储中,如下所示:
Therefore I advice you to use second argument and save state to the localstorage in it, something like this:
this.setState({
titleOne: event.target.value,
},
() =>
{
localStorage.setItem('Furball_Default', JSON.stringify(this.state));
});
这篇关于在我的React应用程序中实现localStorage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!