What is a State Tree in React JS - reactjs

I am new to ReactJS and finished parts of my ReactJS courses that I was taking until I came across Redux where it was talking about uses of Single State tree. I want to know what a state tree actually means

I agree #A.M Usmani
A state tree isn't anything special, it's literally just the state object. A 'single state tree' refers to the fact that in Redux, you have ONE state tree (object) which everything connects to. A single state object that acts as the universal source of truth for your application's stateView
create visualization for the state of each component eg like below picture and
Categorize each reducer like below
const headerReducer = combineReducer({
menu: menuReducer,
search: searchReducer,
location: locationReducer
});
const rootReducer = combineReducer({
header: headerReducer,
login: loginReducer,
footer: footerReducer,
common: commonReducer,
product: productReducer,
catalog: catalogReducer,
payment: paymentReducer
});
Please go through this link you will get good understanding : https://www.freecodecamp.org/news/the-best-way-to-architect-your-redux-app-ad9bd16c8e2d/

Related

How to access arcgis map via components?

The code below is taken directly from arcgis via react on how to display a map.
If i wanted to say, zoom in to a set of coordinates, but the code for that was set in another component, how can i get that component to talk to the map here in this component?
import Map from '#arcgis/core/Map';
import MapView from '#arcgis/core/views/MapView';
const map = new Map({
basemap: "topo-vector"
});
const view = new MapView({
container: "viewDiv",
map: map
});
I resolved this by using redux toolkit to set the map as a global state object.
The entire map view is set in a useEffect, once i initialize each of the views, i dispatch the map view to a reducer in rtk.
dispatch(updateMapViewState(view));
updateMapViewState: (state, action) => {
state.view = action.payload
},
Then, when i want to use the map in a separate component, i do:
const view = useSelector((state) => state.MapSlice.view);
In this way, all components can access the map outside of the useEffect in the map component, and can manipulate it without creating a new map view. This worked for me. I assume you could probably do this with context api, but we aren't using that as a global state manager.
This may not be the recommended or best way to achieve this, but I had success by passing the view object from the map component back to the parent component, then saving it to the parent component's state.
// in App.js
saveViewToState(view){
this.setState({view: view})
}
<MapComponent saveViewToState={this.saveViewToState}/>
// in MapComponent.js
let view = new View()
this.props.saveViewToState(view)
Then I was able to interact with the view object from the parent:
// in App.js
this.state.view.extent = {xmin: 1, ymin: 1, xmax: 2, ymax: 2}
This doesn't work perfectly (for some reason I can't call view.goTo, but view.extent works). I'd be keen to hear if there is a better way to achieve this.
Still looking for a clear answer to this problem.
Have not found an example separating the map/view creation and adding layers into differing components.

React Redux, replacing state history

I am developing an app where I have one Canvas.
Users can choose to duplicate this canvas to save their achievement.
My question is when they come back to this canvas, is it possible to erase the actual state history and replace it by the canvas one in react-redux ?
Is there an efficient way to replace a state history by another in redux?
I could try by directly changing it in the store, but it's a bit dirty...
Here is some snippets of my code:
Store
const store = createStore(combineReducers({
historyCanvas,
canvasDrawing
}));
Reducers
var stateCanvasDrawing = {
lines = [{id:1, strokes: [..] }, {id:2, strokes: [..] }]
}
var stateHistoryCanvas = {
history = [{id: history1, state: {present: [..], past: [..], future:[..]}]
I store states in the historyCanvas reducers:
Then by clicking on a icon, I am able to retrieve the state I want to replace:
var tempState = state.stateHistoryCanvas[0]['state'];
And then I want to do something like that:
store.getState()['stateCanvasDrawing'] = tempState;
in order to replace the actual state by the state I retrieve.
That would be easy with just redux.
But I'm using redux-undo, so how could I copy the entire history I have stored in 'stateHistoryCanvas' to the new state? I don't want to copy only the
but also the state['future'] state['past']
Hope it's clear,
Thank you all,

How to define state?

Does anyone have a good definition for state in the context of a web app?
And more specifically: what does state mean in the context of React - does that differ at all from the first definition?
I see the term state being used a lot in React development but I haven't been able to find a solid, concise definition for it.
State in the context of both cases (react and web apps) is the same.
From wikipedia
In information technology and computer science, a program is described as stateful if it is designed to remember preceding events or user interactions; the remembered information is called the state of the system.
The important part of that quote is remember preceding events or user interactions.
In a web app
State is typically stored in a database somewhere. The web app retrieves the 'state' (data) from the database, presents a view that allows the user to interact with the state, then sends the new 'state' (data) back to the database.
In react
React can be thought of as presenting the 'state' of an application to the user. Data is retrieved from somewhere, react displays the data (state) to the user, allows the user to modify it, and then sends it back to where it found it (remembering).
However, when people talk about 'state' in the context of react, they are generally referring to the internal representation of the data or interactions that react is holding in memory while the user is busy interacting with it.
A simple react component that holds some state:
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {
userName: 'Leeloo'
};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
const name = (this.state.userName === 'Leeloo') ? 'Korben' : 'Leeloo'
this.setState({
userName: name
})
}
render() {
return ( <
button onClick = {
this.handleClick
} > {
this.state.userName
} <
/button>
);
}
}
ReactDOM.render( < Toggle / > , document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
In the example above, the component creates some state and stores it in a 'state' property of the class.
It is remembering it's internal state.
When the component renders, it looks up the value stored in state and displays it on the button label. When the button is clicked, this.state is updated to 'remember' the event of clicking the button.
In a full featured web app, you would be retrieving data from a database, storing that data in state, allowing the user to interact with it, then sending that data back to the database.
For example, you might display a user profile page, the user changes their name, password, description, etc... You would store the 'state' of all the changes they made on that page until they click a submit button. Then you could gather up all the changes from the components state and send it back to the database for storage (remembering).
Also, you may want to store state in a react component to describe how the appearance of the app should be based on interactions with it. For example, an InputBox component may have a hasError state and when true, adds a red border to the component.
General: State is all data currently stored by the application.
In context of React: State is an object that defines - besides props - how a component is rendered. State can be (unlike props) changed by the component itself.

Loading static constants in React+Redux

I'm using server side rendering for my React-Redux application. And I want at application startup to load some constants, for example list of cities with corresponding IDs:
[
{
name: "London",
id: 1
}
...
]
I think it's better to put this data into store on server side and provide it to client using window.__INITIAL_STATE__ as suggested here http://redux.js.org/docs/recipes/ServerRendering.html
This constants will be read-only, and I want to preload them just for data normalization purposes. For example later I can just retrieve list of users with city IDs, instead of users with city names: {name: "Alex", cities: [1,2]}
The problem is that if I put them into store, then I forced to create reducer for this constants, otherwise I'm getting this error:
Unexpected key "cities" found in preloadedState argument passed to
createStore. Expected to find one of the known reducer keys instead:
"colors". Unexpected keys will be ignored.
So I'm searching for some elegant way to handle this situation.
For now I have 2 ideas how to handle it:
Create empty reducer which always will return default state
export const cities = (state = [], action={ type: null }) => {
return state
}
Send from server initial actions with payloads, and execute them on client at startup:
// server.js
window.INITIAL_ACTIONS = [
{ type: "REQUEST_LOGIN_SUCCESS", user: {userId, userName, userEmail, etc} },
{ type: "REQUEST_CITIES_SUCCESS", [..listOfCities] },
]
And in my client-index.js, dispatch those actions right after creating the store:
//client-index.js
window.INITIAL_ACTIONS.forEach(store.dispatch)
So, is one of my approaches is good? Or may be you know some other, more elegant solution?
Thanks.
We do something similar with a dummy "settings" reducer. i.e.
const rootReducer = combineReducers({
...
settings: (state = {}) => state,
...
});
This gives us a convenient place to store all our app config.
Just make sure you key your initial state in the same manner. i.e.
window.__INITIAL_STATE__ = {
...
settings: { ... },
...
};
Some may object to this practise, but I think it's sound. Though settings may be constant, it is nonetheless state. It conforms to the redux practice of a single state object. (Besides, there may come a future point where the settings state slice will be dynamic and require a "real" reducer.)

in react Redux how to structure app to decouple component from state atom

in an redux app, using connect to fetch data from state is the way to go. problem is i find my self tighly coupling the component with the state atom.
in case i want to change the structure of the state tree, all components that used to consume such state will break.
so how to decouple them ?
example
initialState = {
users: { ids:[1,2] , byId:{1:{name:'user 1'},2:{name:'user 2'} }
posts: { ids:[1,2] , byId:{1:{title:'post 1'},2:{title:'post 1'} }
access : {1:[1,2],2:[1,2]} //post_id : [user_id who can see post]
}
in this simple state, i'm descriping that i have 2 users, and 2 posts, both posts are visible to both users..
in a component that list posts and users the connect can be
render(){
let {posts,access,currentUser} = this.props;
let my_posts = posts.ids.map(post_id=>posts.byId[post_id])
.filter(post=>(access[post.id].indexOf(currentUser.id)>-1)
//above map will return posts, and filter will filterout posts user dont have access to.
}
connect( (state,prop)=>{currentUser:users[prop.user_id],posts,access})(Component);
<Component user_id={1} />
the problem here is that the render function of the component do lots of manipulation with the state to render correct data. it would be much better if i can do something like
render(){
let my_posts = Posts.ofUser(currentUser.id)
//now Posts should be a service that has access to state and return the needed data.
}
how can i create such Object that deals with the state and expose an api that components and connect functions contact for information.
i read about reselect alot, but how to implement it ?
The easiest way to decouple state shape from your components is querying any of your state prop through selectors.
It adds a bit of boilerplate code, but once is done, you'll get a fully testable bridge between your components and application state.
To get started with selectors, take a look to Redux Docs Computing derivated data page.
Reselect is just an utility to create memoized selectors.

Resources