I am trying to figure a silly error, hope someone can help me to understand it better.
setServerList(data.data) doesn't set the data, its still empty when I tried to use it.
export const KernelUpdateSearch = (props: RouteComponentProps) => {
const [serverList, setServerList] = useState<any>([]);
// searchHost perform GET request to gannet for aggregate count
const searchHost = async (hostRegex: string) => {
try {
const response = await fetch("URL", {
mode: 'cors',
method: 'GET',
headers: requestHeaders
});
const data = await response.json();
if (data.success === true) {
if (data.data != null && (data.data.length > 0)) {
setServerList(data.data);
} else {
setServerList([])
console.log('no data found, status code: ', response.status);
}
} else {
console.log("failed to query, error: ", data.error.message);
}
} catch (error) {
console.log(error);
}
};
const handleSubmit = (formInstance: FormEventReturn) => {
handleChange(formInstance)
};
const handleChange = ({formData}: FormEventReturn) => {
searchHost(formData.hostname);
console.log(serverList);
};
return (
<Card options={searchOptions}>
<Form
schema={searchSchema}
uiSchema={uiSchema}
onSubmit={handleSubmit}
/>
</Card>
);
};
CodePudding user response:
How can i setServerList is persistent after handleChang event.
You have two options:
export const KernelUpdateSearch = (props: RouteComponentProps) => {
const [serverList, setServerList] = useState<any>([]);
// searchHost perform GET request to gannet for aggregate count
const searchHost = async (hostRegex: string) => {
let newServerList = [];
try {
const response = await fetch("URL", {
mode: 'cors',
method: 'GET',
headers: requestHeaders
});
const data = await response.json();
if (data.success === true) {
if (data.data != null && (data.data.length > 0)) {
newServerList = data.data;
} else {
console.log('no data found, status code: ', response.status);
}
setServerList(newServerList);
} else {
console.log("failed to query, error: ", data.error.message);
}
} catch (error) {
console.log(error);
}
//
// 1a - return new server list
//
return newServerList;
};
const handleSubmit = (formInstance: FormEventReturn) => {
handleChange(formInstance)
};
const handleChange = ({formData}: FormEventReturn) => {
searchHost(formData.hostname)
.then(serverList => {
//
// 1b - get returned serverList or empty array
//
console.log(serverList);
});
};
//
// 2 - be notified when there are new servers
//
useEffect(() => {
if (serverList.length > 0) {
console.log(serverList);
}
}, [serverList]);
return (
<Card options={searchOptions}>
<Form
schema={searchSchema}
uiSchema={uiSchema}
onSubmit={handleSubmit}
/>
</Card>
);
};
** Edit **
Whether you need serverList
as a state variable or not, consider this refactor to make things more readable (i.e. less confusing) :
// ---- utility can be imported from a different module ----
// searchHost perform GET request to gannet for aggregate count
const searchHost = async (hostRegex: string) => {
let serverList = null;
try {
const response = await fetch("URL", {
mode: 'cors',
method: 'GET',
headers: requestHeaders
});
const data = await response.json();
if (data.success === true) {
if (data.data != null && (data.data.length > 0)) {
serverList = data.data;
} else {
serverList = [];
console.log('no data found, status code: ', response.status);
}
} else {
console.log("failed to query, error: ", data.error.message);
}
} catch (error) {
console.log(error);
}
return serverList;
};
// -------------- React component below -------------
export const KernelUpdateSearch = (props: RouteComponentProps) => {
const [serverList, setServerList] = useState<any>([]);
const handleSubmit = async ({formData}: FormEventReturn) => {
searchHost(formData.hostname)
.then(newServerList => {
// only update state if the returned value is non null
if (newServerList) {
setServerList(newServerList);
}
});
};
useEffect(() => {
if (serverList.length > 0) {
// new servers available!
console.log(serverList);
}
}, [serverList]);
return (
<Card options={searchOptions}>
<Form
schema={searchSchema}
uiSchema={uiSchema}
onSubmit={handleSubmit}
/>
</Card>
);
};
Normally, event handlers should be small and simple. Having things inside useEffect
is an abstraction that allow you to update the list from any means and have the processing at a central location.