React: Action on Variable Change

React: Action on variable change

Finally solved

componentDidUpdate(PrevProps, prevState){
if(this.state.cmbID !== prevState.cmbID){

this.reload2()
}
if(this.state.ID !== prevState.ID){

this.reload3()
}
}

How to detect a variable change in React js/Solidity?

If you are using functional components you can use the useEffect hook,
like this

useEffect(()=>{
//call your increment function here
},[someVariable]) //and in the array tag the state you want to watch for

the useEffect will cause a re-render when the state of 'someVariable' in the above example changes

you can see more about the hook in the react docs https://reactjs.org/docs/hooks-effect.html,

Special actions on React state variables

You should never mutate your state, not even in a reducer function.

From the docs:

If you return the same value from a Reducer Hook as the current state, React will bail out without rendering the children or firing effects. (React uses the Object.is comparison algorithm.)

Change your reducer to return a new object:

const ProfilesReducer = (state, action) => {
switch (action.type) {
case 'addNewProfile':
{
const newProfile = action.newProfile;
return {...state, profiles: [...state.profiles, newProfile]}
}
break;
default:
throw new Error('Unexpected action type: ' + action.type);
}
return state;
}

Also not that reducer should no have side effects, if you want to perform some action based on a state change, use a useEffect hook for that.

For example:
DataManager.addNewProfile(newProfile) should not be called from the reducer

How to listen to a count variable change and trigger actions depending on its value

Since the counter is only updated by your code, you can directly add the check after you increment the count.

var count = 0;
counter.innerHTML = count + "/30";
var x = document.getElementById("changed");

document.getElementById("button").onclick = function() {
count++;
if (count >= 5) {
x.style.color = "red";
}
counter.innerHTML = count + "/30";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="counter">
Counter
</div>
<div id="button">Click to add 1
</div>
<div id="changed">This must turn red when counter >= 5
</div>

React: State of a variable changes, but UI Icon dosen't get updated

I solved my problem by creating 2 different Icon components.
Icon and IconDark and conditionally rendering them inside the NavButton component.
Not sure if it is the "correct" way of doing things but it got the job done.
I'm going to guess the reason why it didn't render the colors correctly earlier is because of the attribute "color" inside the component. I think JSX just took it in as another prop and did nothing with it after the first render of the element.

edit 1: nvm it definitely didn't get the job done. At least not well enough. The icon swap in the render isn't fast enough so it causes the user to see the icon swap.

edit 2: This article held the answer that I needed.

https://dev.to/abachi/how-to-change-svg-s-color-in-react-42g2

It turns out that to change an svg color with react you need to set the initial fill (or for me color) value inside the svg component to "current" and then pass the real value in from the parent element conditionally.

Long story short - Controlling SVG values is a little different to controlling text values in react.

How to modify a redux variable state from react component with a button click?

You need to modify your reducer to actualy do something with paylad:


const processReducer = (state = 0, action) => {
switch (action.type) {
case "ID":
return action.payload;
default:
return state;
}
};
export { processReducer };

make your action to pass id as payload (i would consider to use something better as name of action instead of id):

export const id = (id) => {
return {
type: "ID",
payload: id,
};
};

and then call your action onclick using dispatch with this ID

const ChangeState = () => {
const id = useSelector((state) => state.id); //initial state of id=0
const dispatch = useDispatch();
return (
<div>
<button onClick={()=>dispatch(id(1))}>button1</button>
<button onClick={()=>dispatch(id(1))}>button2</button>
</div>
);
};

Execute Function when a State Variable Changes inside of a useEffect() Hook

Store graph in a React ref so it persists through rerenders. In hideN use an Optional Chaining operator on graphRef.current to call the findById function.

Add hideNode state as a dependency to the useEffect hook and move the hideN call out of the conditional block that is only instantiating a graph value to store in the ref.

const graphRef = useRef(null);
const ref = useRef(null);

//Hide Node State
const [hideNode, sethideNode] = useState("");

const hideN = () => {
const node = graphRef.current?.findById(hideNode);
node.hide();
};

useEffect(() => {
if (!graphRef.current) {
graphRef.current = new G6.Graph(cfg);
graphRef.current.data(data);
graphRef.current.render();
}
hideN();
}, [hideNode]);

React + Mobx How to change value from different components and show changes everywhere?

I found sulution with React Context.
Sorry for not adding here right away.
Unfortunately, it is difficult to understand the Mobx documentation.

https://codesandbox.io/s/react-mobx-change-value-in-several-components-forked-using-react-context-e1mjh

First, we need to make context and create provider:

https://codesandbox.io/s/react-mobx-change-value-in-several-components-forked-using-react-context-e1mjh?file=/src/AppStoreProvider.js

import { useLocalStore } from "mobx-react";
import React from "react";
import AppStore from "./AppStore";

export const AppStoreContext = React.createContext();

export const AppStoreProvider = ({ children }) => {
const store = useLocalStore(AppStore);
return (
<AppStoreContext.Provider value={store}>
{children}
</AppStoreContext.Provider>
);
};

export const UseAppStore = () => React.useContext(AppStoreContext);

export default AppStoreProvider;

Where the AppStore.js is:

import { action, makeObservable, observable } from "mobx";

export default function AppStore() {
return makeObservable(
{
text: "Initial text",
changeText(data) {
this.text = data + ": " + new Date().toLocaleTimeString();
}
},
{
text: observable,
changeText: action
}
);
}

https://codesandbox.io/s/react-mobx-change-value-in-several-components-forked-using-react-context-e1mjh?file=/src/AppStore.js

Then, we need to wrap our main render in index.js with :

import { StrictMode } from "react";
import ReactDOM from "react-dom";
import AppStoreProvider from "./AppStoreProvider";

import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(
<AppStoreProvider>
<App />
</AppStoreProvider>,
rootElement
);

https://codesandbox.io/s/react-mobx-change-value-in-several-components-forked-using-react-context-e1mjh?file=/src/index.js

And then we can use context:

import "./styles.css";
import React from "react";
import { UseAppStore } from "./AppStoreProvider";
import { observer } from "mobx-react";
import SomeComponent from "./SomeComponent";

const App = observer(() => {
const store = UseAppStore();

return (
<div className="App">
<div>
<i>This is text in App:</i> {store?.text}
</div>
<div>
<button
onClick={() => {
store.changeText("This is text from App");
}}
>
Change text from App
</button>
</div>

<SomeComponent />

</div>
);
});

export default App;

https://codesandbox.io/s/react-mobx-change-value-in-several-components-forked-using-react-context-e1mjh?file=/src/App.js

Or like this:

import { useContext } from "react";
import { AppStoreContext } from "./AppStoreProvider";
import { observer } from "mobx-react";

const SomeComponent = observer((props) => {
const store = useContext(AppStoreContext);

return (
<div>
<div>
<i>This is text in component:</i> {store.text}
</div>
<div>
<button onClick={() => store.changeText("This is text from component")}>
Change text from component
</button>
</div>
</div>
);
});

export default SomeComponent;

https://codesandbox.io/s/react-mobx-change-value-in-several-components-forked-using-react-context-e1mjh?file=/src/SomeComponent.js

Hope it comes in handy for someone

redux state automatically change when variable change

You shouldn't mutate the state. State should be immutable and should be always computed through redux reducers.

You should only read from the state at this point.

In your case dispatching a redux action with delivery as payload, and catching it in reducer by adding it to the state would be the way to go.

See todo example.



Related Topics



Leave a reply



Submit