-
Notifications
You must be signed in to change notification settings - Fork 693
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added week2 homework #208
Added week2 homework #208
Conversation
State is saved on local storage but I need to figure out how I can make class name update from local storage on reload. |
…al storage when that is available
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @neveenatik , I see your Hard efforts, I think that you can improve better and better 💪.
You have a very nice files separating, and you still missing some concepts to understand yet.
so I left some comments about the main things you may make an attention on, and may help you going out through this, I dropped out any thing that may not really arrive to the main point we want to arrive.
I am highly encourage you to make an attention to these comments if something you didn't understand we feel free to ask 🙂.
homework-submission/week2/src/App.js
Outdated
const indexOfItem = newState.items.findIndex(item => item.id === id); | ||
let targetItem = newState.items[indexOfItem]; | ||
if (indexOfItem >= 0) { | ||
targetItem.done === true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of this you can just say targetItem.done ? // rest of the code
homework-submission/week2/src/App.js
Outdated
: (targetItem.done = true); | ||
} | ||
localStorage.setItem("items", JSON.stringify(newState.items)); | ||
this.setState({ items: newState.items }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have a very nice way of updating the state here, But you are modifying the state immediately, you can test this instead of yours and you will find out that you are doing it:
let newState = Object.assign({}, this.state);
const indexOfItem = newState.items.findIndex(item => item.id === id);
console.log(this.state.items[indexOfItem].done); // this will show you the previous state
let targetItem = newState.items[indexOfItem];
if (indexOfItem >= 0) {
targetItem.done
? (targetItem.done = false)
: (targetItem.done = true);
}
console.log(this.state.items[indexOfItem].done); // this will show you the next state before setting it !!
this.setState({ items: newState.items }, () => {
console.log(this.state.items[indexOfItem].done); // this should have the next state
});
So it would be better to use for a .map
method here that doing all of these for you and it's just more readable for others.
So you may make it as
this.setState({
list: this.state.list.map(item => {
if (item[id] === id ){
// return a new Object that contains the new data we need
return {
...item, // using the spread operator we will copy the elements inside of `item` and replace the `done` with a new value
done: !item.done
}
}
return item
})
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Jawhar,
Thank you very much for your feedback. It is a very useful tip.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't understand how I was setting the state directly since I am manipulating the new instance of it ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry being late, I didn't saw this reply till the day.
yes you are mutating the state; because you have in line 19 a, Object.assign
which in your case is just assigning a new reference to the old one.
according to mdn
The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.
in this case it's only copying the values of the Object as a references 💔.
what you may do for a deeper copy is by initializing a new source Object in the third parameter so it will be a complete new Object:
const setState = Object.assign({}, this.state, {/* the object with the new values */})
Js is wired sometimes I have no 100% correct explanation for what is happening here more than What I said.
homework-submission/week2/src/App.js
Outdated
}; | ||
|
||
componentDidMount() { | ||
let itemsCopy = localStorage.items; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is only for localStorage
as I see, so you may use componentWillMount
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's right I am saving changes to localStorage as well so on refresh state is not reset to initial state. As far as I know componentWillMount
depreciated in react 16.3 and will be removed the next major version.
Do you think then it is better maybe to set state in the constructor
it is called before componentWillMount
right?
I read this interesting article.
https://daveceddia.com/where-fetch-data-componentwillmount-vs-componentdidmount/
please let me know what do you think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
homework-submission/week2/src/App.js
Outdated
componentDidMount() { | ||
let itemsCopy = localStorage.items; | ||
|
||
if (itemsCopy !== undefined) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can only say if (itemsCopy) {/* Do something */}
return ( | ||
<ul className={this.props.Title}> | ||
{this.props.todoItems.map(item => ( | ||
<div key={"wrapper" + item.id}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By looking to the mdn
documentation we will find underneath the example table that the ul
tag doesn't accept a div
tag as a child and that may have some unexpected behaviors in the term of not following the generic rules.
const { type, id, done, handleChecked } = this.props; | ||
return ( | ||
<input | ||
key={type + id} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this key.
you are not iterating to repeat this line inside of an array to be sure that you should have it.
and there is another place you have un-needed key you should remove, if you get the Idea of it 🙂.
<input | ||
key={type + id} | ||
type={type} | ||
className={done === true ? "checked" : "unchecked"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can just say done ? "checked" : "unchecked"
Thanks for your review @JawharBairakdar I made all needed changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice Work 💯.
you did a great job submitting the state review.
it was all about it so I am not going to ask for any further changes.
plus I see your Great vision on the React Updates 🎉.
Thanks for review, and sorry that I delivered just now.
I forgot to make a PR.