I am using the MUI progress bar in order to show the process and manually setting the value of the progress by a variable. The functional component renders well and I can update the value of the progress bar but it seems it does not work after the api call. Also I am updating the value of the progress bar while my search takes place and the results are being sent as params to another component onSearchComplete.
function LinearProgressWithLabel(props: LinearProgressProps & { value: number }) {
return (
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Box sx={{ width: '100%', mr: 1 }}>
<LinearProgress variant="determinate" {...props} />
</Box>
<Box sx={{ minWidth: 65 }}>
<Text><Typography variant="body2">{`${Math.round(
props.value,
)}%`}</Typography></Text>
</Box>
</Box>
);
}
export const Search = (props) => {
const { contacts, setContacts, onSearchComplete } = props;
const [msgBox, setMsgBox] = useState(null);
const [loading, setLoading] = useState(false);
const [progress, setProgress] = useState(10);
let progressValue = 0;
const onSearch = async () => {
setLoading(true);
progressValue = 30;
try {
//setting progressValue = 60 here works fine.
const searchResults = await AppApi.searchMany(emails); //making the api call
progressValue = 80; //this value does not work
let userList = [];
for (let i = 0; i < searchResults.length; i ) {
//processing the result here.
}
userList = [...userList, ..._users];
}
progressValue = 95;
userList.sort(sortByEmail);
onSearchComplete(userList);
} catch (err) {
console.log({ err });
setMsgBox({ message: `${err.message}`, type: 'error' });
}
setLoading(false);
}
useEffect(() => {
onSearch();
}, []);
useEffect(() => {
setProgress(() => progressValue);
}, [progressValue]);
return (
<Box>
{loading ? <LinearProgressWithLabel value={progress} />:
<Box>{msgBox && (<a style={{ cursor: 'pointer' }} onClick={() => setMsgBox(null)} title="Click to dismiss"><MessageBox type={msgBox.type || 'info'}>{msgBox.message}</MessageBox></a>)}</Box>}
</Box>
);
}
CodePudding user response:
progressValue
will be redeclared 0
each render cycle. Just enqueue state updates to the progress
state.
export const Search = (props) => {
const { contacts, setContacts, onSearchComplete } = props;
const [msgBox, setMsgBox] = useState(null);
const [loading, setLoading] = useState(false);
const [progress, setProgress] = useState(10);
const onSearch = async () => {
setLoading(true);
setProgress(30);
try {
const searchResults = await AppApi.searchMany(emails);
setProgress(80);
let userList = [];
for (let i = 0; i < searchResults.length; i ) {
//processing the result here.
userList = [...userList, ..._users];
}
setProgress(95);
userList.sort(sortByEmail);
onSearchComplete(userList);
} catch (err) {
console.log({ err });
setMsgBox({ message: `${err.message}`, type: 'error' });
}
setLoading(false);
}
useEffect(() => {
onSearch();
}, []);
return (...);
}