use-force-update
use-force-update copied to clipboard
Update component from other components function.
Nice package and it works like expected! I would like to ask if something like this is possible but for now, everything I tried did not work.
import Nav from './nav';
const myFunc= () => {
forceUpdate(<Nav />);
};
The problem I face that the function that runs on the click is in another component then the component that needs force-rerender, Is there any way to achieve this? Thanks
forceUpdate uses React state, so it can only exist from the context of a React component (passed as props to other component children), or else it has to be stored in global state.
It looks like you want a component other than Nav to force update the Nav component. In nav, you would create the force update function (because it is stateful and that state belongs to the Nav component) with function Nav() { const forceUpdate = useForceUpdate(); ... } The goal is then to get that forceUpdate function to whatever component/utility is calling it. If that component is a child node, passing it as props is easiest. If that component is a sibling or if the calling code is a utility file, you may want to use global state to store the forceUpdate function and call it from the global state. I don't recommend using window, but as an example, window.forceNavUpdate = useForceUpdate() and then window.forceNavUpdate() from the utility file.
For some reason use-force-update stopped working in my project since there are no issues in this repo it's hard for me to find out where the error is because I also have no errors in console, I use it in Electron/React app and it worked then it stopped working one time. I do nothing else then in the example, import package, then const forceUpdate = useForceUpdate(); then call it somewhere in a function. I have tested the functions they are working normally I know this because I see the result when I refresh my Electron app manually but the forceUpdate is not forcing my component to rerender any idea what it could be?
The best attempt at debugging would require you share the code in question -- preferably a minimal reproduction.
Here the component, the force update in on like 57 in the removeAccount Function.
import React, { useState, useContext } from 'react';
import { AccountsContext } from '../../context/AccountsContext/AccountsContext';
import useForceUpdate from 'use-force-update';
import { makeStyles } from '@material-ui/core/styles';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';
import ListItemText from '@material-ui/core/ListItemText';
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
import Checkbox from '@material-ui/core/Checkbox';
import Avatar from '@material-ui/core/Avatar';
import Button from '@material-ui/core/Button';
import lowdb, { low, FileSync, adapter, db, AccountsArray } from '../../lowdb';
const useStyles = makeStyles(theme => ({
root: {
width: '100%',
backgroundColor: '#282a36'
}
}));
function Accounts() {
const [accountname, setAccountname] = useContext(AccountsContext);
const [checked, setChecked] = useState([1]);
const [remove, setRemove] = useState('Remove');
const classes = useStyles();
// Force Update Hook.
const forceUpdate = useForceUpdate();
// Checkbox Logic
const handleToggle = value => () => {
const currentIndex = checked.indexOf(value);
const newChecked = [...checked];
if (currentIndex === -1) {
newChecked.push(value);
setRemove(value);
} else {
newChecked.splice(currentIndex, 1);
}
setChecked(newChecked);
};
// Handler Functions
const handleChange = e => {
setAccountname(e.target.value);
};
//Remove Account from db
const removeAccount = () => {
try {
db.get('accounts')
.remove({ name: remove })
.write();
forceUpdate();
} catch (error) {
console.error(error);
}
};
return (
<React.Fragment>
<Button onClick={removeAccount}>Remove</Button>
<p>{accountname}</p>
<input
className="input is-small"
type="text"
placeholder="Accountname"
value={accountname}
onChange={handleChange}
/>
<List dense className={classes.root}>
{AccountsArray.map(value => {
const labelId = `checkbox-list-secondary-label-${value.id}`;
return (
<ListItem key={value.id + value.name}>
<ListItemAvatar>
<Avatar />
</ListItemAvatar>
<ListItemText id={labelId} primary={value.name} />
<ListItemText id={labelId} primary={value.id} />
<ListItemSecondaryAction>
<Checkbox
edge="end"
onChange={handleToggle(value.name)}
checked={checked.indexOf(value.name) !== -1}
inputProps={{ 'aria-labelledby': labelId }}
/>
</ListItemSecondaryAction>
</ListItem>
);
})}
</List>
</React.Fragment>
);
}
export default Accounts;