Copy state object without some fields - javascript

I need to transfer state of a component to its parent component, but I don't need to transfer all fields.
What I currently do:
submitHandler = (e) => {
e.preventDefault();
const newState = Object.keys(this.state).map(item => {
if(item !== 'errors')
{
return { item: this.state[item] }
}
});
console.log(newState);
this.props.onChange(newState);
}
Obviously it is not what I need.
state = {
errors: {
fio: '',
email: '',
phone: ''
},
owner: owner.Company,
fio: null,
company: null,
phone: null,
fax: null,
email: null,
adress: null
}
I need to transfer all field except errors. How can I do that?

You can use the rest operator for making it work :)
const { errors, ...newState } = this.state;
this.props.onChange(newState);
I put an example here :) https://repl.it/#EQuimper/PleasantTrimDeclarations

Object destructuring with the rest operator provides a convenient way to copy objects, while omitting specific fields. In the example below, newState will be a copy of this.state, minus the errors property:
submitHandler = e => {
e.preventDefault();
const { errors, ...newState } = this.state;
this.props.onChange(newState);
};

Related

setState of dynamic multidimensional object

I have a state like this.
insetts: {
cid: {
checked: false,
value: "",
},
name: {
checked: false,
value: "",
},
...
},
outsetts: {
...
},
...
the event handler will receive the name of each level and update the fields checked and value of the checked item.
(the outer level is accessed through props - this.props.which)
I need to update
const target = evt.target.value;
this.state[this.props.which][target].checked
How can I use setState?
I've tried:
this.setState({
[this.props.which]: {
...this.state[this.props.which],
[evt.target.value]: {
...this.state[this.props.which][target],
checked: true
}
}
}
);
and some variants of it but to no avail.
Thanks
EDITED
it is working with the cloning approach recommended by #Vo Quoc Thang
const target = evt.target.value;
const cloned = JSON.parse(JSON.stringify(this.state[this.props.which]));
cloned[target].checked = true;
and both of the following approaches:
this.setState((prevState) => {
return {
...prevState,
[this.props.which]: cloned,
};
});
or
this.setState({ ...this.state, [this.props.which]: cloned });
You can clone the object first, modify it and update to your state
const attr = this.props.which;
const cloned = JSON.parse(JSON.stringify(this.state[attr]));
cloned[evt.target.value].checked = true;
this.setState({attr : cloned});

Change Nested State Value With A Single Function? (javascript/React)

I have some react user privilege state data I need to manage. I would like the ability to change the object privileges based on their property through a dynamic function. I'm not sure how to target the specific nested privilege property to change the value. Is this possible?
Question: How can I change the value of a nested privilege property to the functions type and value parameter?
Heres an Example:
const [userPrivilages, setUserPrivilages] = useState([{
_id: "123"
privilages: {
edit: true, //before!
share: true,
del: false
}
},
{
...more users
}
])
//my attempt
const changePrivilage = (type, value) => {
const newPrivilages = userPrivilages.map(user => {
return {
...user,
privilages: {
...privilages,
//change the privilage of "type" from the functions parameter to the value parameter
}
}) setUserPrivilages(newPrivilages)
}
changePrivilage("edit", false)
Desired output:
const [userPrivilages, setUserPrivilages] = useState([{
_id: "123"
privilages: {
edit: false, //After!
share: true,
del: false
}
},
{
...more users
}
])
Thanks!
You can use [] to refer to variable as a key like below:
const changePrivilage = (type, value) => {
const newPrivilages = userPrivilages.map(user => {
return {
...user,
privilages: {
...user.privilages,
[type]: value // here it is !!!
}
}) setUserPrivilages(newPrivilages)
}
Try this :
(see comments for understanding code)
const changePrivilage = (type,value) => {
const newUserPrivilages = userPrivilages.map(user => {
let newPrivilages = user.privilages; // get old privilages of user
newPrivilages[type] = value; // update type with new value
return {
...user,
privilages: newPrivilages, // set privilages as newPrivilages
};
});
setUserPrivilages(newUserPrivilages);
};
Note : this will change properties for all users. If you want to update only for specific user, pass _id as well to changePrivilage and execute newPrivilages[type] = value; // update type with new value inside if condition comparing user _id.

How to add new child key-value to a React State object

I'd like to add a new child key-value to an existing partent -happening on React. Let's say this is my state:
this.state = {
genres: {
Rock: '',
Jazz: '',
Pop: ''
}
}
And this is my method:
addingGenre(tw) {
this.setState({
genres: { [tw]: '', }
})
}
This is obviously not working, itoverwrites my full state --> {genres: tw}.
Thanks so much in advance :)
You need to push to the current state. So it should be something like this:
addingGenre(tw) {
this.setState({
genres: { ...this.state.genres, [tw: '']}
})
}
You can do it like this -
addingGenre(tw) {
const state = this.state;
state.genres[tw] = '';
this.setState(state)
}

How to properly reset Vue Composition Api's reactive values

I'm wondering how should I reset a reactive in vuejs setup? (i know if change it to the ref and using view.value will solve this problem, but there should be an answer to this for using reactive)
setup(props, context){
// states
const DataTable = reactive((null as unknown) as DataTable);
const PolicyForm = reactive((null as unknown) as PolicyForm);
let view = reactive(resetViewState());
let config = reactive(
(resetPreRegisterConfig() as unknown) as PreRegisterConfig
);
// methods:
const fetchProfilelist = (
pagination: Pagination{ page:1, size:15},
sort_label: string = ""
) => {
DataTable.fetchTablelist(api_fetchProfilelist, pagination, sort_label);
};
const pageRefresh = () => {
view = resetViewState(); // 👈
config = resetPreRegisterConfig();
fetchProfilelist();
};
return {
DataTable,
PolicyForm,
view,
config,
fetchProfilelist,
pageRefresh
}
You can use Object.assign:
setup() {
const initialState = {
name: "",
lastName: "",
email: ""
};
const form = reactive({ ...initialState });
function resetForm() {
Object.assign(form, initialState);
}
function setForm() {
Object.assign(form, {
name: "John",
lastName: "Doe",
email: "john#doe.com"
});
}
return { form, setForm, resetForm };
}
See it live on codesandbox
credits: taken from here
Object.assign didn't work for me. (Maybe because I used a shim for the Composition API in Nuxtjs 2?) For anybody that run into the same problem: I had to use a compact loop.
setup() {
const initialState = {
name: "",
lastName: "",
email: ""
};
const form = reactive({ ...initialState });
function resetForm() {
for (const [key, value] of Object.entries(initialState)) {
form[key] = value
}
}
function setForm(values = {name: "John", lastName: "Doe", email: "john#doe.com"}) {
// only loop with the supported keys of initial state
for (const key of Object.keys(initialState)) {
form[key] = values[key]
}
}
return { form, setForm, resetForm };
}
Citing from the official Vueland Discord server:
"For what I know, reactive is the old way we use to do reactivity from the Classic API, so to reset the values should be something like:"
const myData = reactive({
foo: true,
bar: ''
})
function resetValues () {
myData.foo = true
myData.bar = ''
}
Therefore, if you don't change properties you should be able to use Object.assign(). (Correct me if I'm wrong)
How about use ref instead of reactive?
const myData = ref({ xxx: 11 })
// ... After many operations on myData
// resetData
myData.value = { xxx: 11 }
The disadvantage is that you need to add .value when using it in script.
But this is the same as reactive in vue template.
If you have deep objects you can use this trick to reset the values converting them to JSON
setup(){
const form = ref({
order: '',
user:{},
});
const defaultForm = JSON.parse(JSON.stringify(form));
form.value.user = {firstname:"Joe", lastname:"Doe"};
const onSubmit = () => {
// Reset values to default
form.value = JSON.parse(JSON.stringify(defaultForm));
}
}
If you do not want to use ref and want to reset value of a reactive variable then you have to take one key variable for reference in the reactive variable, because reinitializing reactive variable directly will cause to loose reactivity in the process.
So to reset the value use extra key variable in reactive variable, see code as below
setup() {
const initialState = {
name: "",
email: ""
};
const form = reactive({ data: ...initialState });
function resetForm() {
form.data = { ...initialState };
}
function setForm() {
form.data = {
name: "Bahubali",
email: "bahubali#mahismati.com"
});
}
return { form, setForm, resetForm };
}
So basically you are taking data as key of your reactive variable and when you want to reset or set your values you just need to change the form.data and it will be reactive and refreshes the elements which uses form.data.

React - How can I access a particular position in the array, and then change it?

In state, I have an array and would like to access one of the array positions.
For example, in other languages it might be:
usersJson[position] ...
But in the react I can't do:
this.state.usersJson[position] = ...
Can anyone help?
constructor() {
super();
this.state = {
usersJson: []
};
//loads a list of users througth jsonPlaceholder data
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(json => this.setState({ usersJson: json }));
I have tried this:
{this.state.usersJson.map((item => {
if (item.id === props.id) {
return(
item.email = props.email,
item.address = {
street: props.address.street,
suite: props.address.suite,
city: props.address.city,
zipcode: props.address.zipcode,
},
item.phone = props.phone
)
}
return null
}))}
but I want something like
this.setState({userJson[position]: ...})
The array looks like:
usersJson:{
id: ...,
name: "...",
email: "..",
address: {
street: "...",
suite: "...",
city: "...",
zipcode: "..."
},
phone: "..."
}
You can copy your array to a temporary array and then change that array. It would be something like
adjustArray = () => {
const {usersJson} = this.state;
let tempArray = [...usersJson];
tempArray[position] = "something";
this.setState = ({ usersJson: tempArray});
}
In React classes you should only update by using this.setState.
If you don't know what position of the array the user is in then you can use the .find method for arrays. However since you are trying to trying to access JSON, I recommend converting the array that you receive from the API into an object. Then you would be able to access the position with this.state.usersJson[key] where key is whatever you decide to name each object in usersJson.
To update your state based on a property name:
state = {
name : 'John',
surname : 'Doe'
}
handleChange = (name, value) => this.setState(state =>({
...state,
[name] : value
}))
render() {
const { name } = this.state
return <input value={name} onChange={e => this.handleChange('name', e.target.value))}
}

Categories

Resources