I am developing a React Native App and I am implementing my redux store.
And I was wondering if I can store a React Component in the redux initial state like this in my reducer :
import Tache from '../components/Tache';
const initialState = {
tache : [
<Tache props={{
nom : "Nom",
id: "0",
isDetail : false,
parentFunction : ()=> {return null},
listeMembre : ["Hugo", "Theo"],
desc : "Description",
date : "Date",
url : "www"
}}/>
]
}
It works for me but I am wondering if it's a good practise or not at all
Redux is just javascript. You can put whatever you want in there - functions, Dates, Sets, even entire component trees.
However, if you ever want to persist your state - i.e. save it to the device when the app is backgrounded, and reload it when the app is foregrounded - the data must all be serializeable. That means that JSON.parse(JSON.stringify(data)) must return the original data. This only works on primitives, and arrays and objects that hold primitives.
That's why it's considered bad practice to put anything else into your state. It also keeps your state from having "too much responsibility"; your state should tell your components what to display, and not handle any of the actual display.
No, Very bad practice. You should store only data in the redux not the jsx code.
why do you want to do this? I don't think that's the best practice, if you want to use the component multiple times you can implement conditional logic for that and make this component dependent on its result.
Redux or any global state management library is just for data management(add/delete/update etc), not for components storing.
Related
i just want to know this.whether state json object binding and normal json object binding is same or not? below is the example.
1st example
state = { name: "Default", email: "" };
binding data : this.state.name
this.setState({ name: e.currentTarget.value })
2nd example
const data= {name: "Default", email: ""}
binding data to control: data.name
onchange={e=>data.name=e.value}
both are working fine but want to know which one is better in performance?
my application dosent need any imutable data because i not displaying data dynamically i need to fetch the data from api on component load and posting the data to api on form submit. so i am using the 2nd approch. where i feel state will unnecessarly load render object.
so can any one suggest which one is better?
If the state is not associated with any UI component then changing it will not re-render anything so functionally both will work the same.
In terms of performance 2nd approach will be faster as it is a direct object manipulation whereas calling setState is a function call and doesn't guarantee immediate execution.
However do not use 2nd approach at all because it will create confusion for the next developer who manages such code(In my opinion). In the long run when the data grows you will have to keep a separate state obj for managing the data and the UI.
So it is always better to keep them separate from the beginning.
What's an efficient/elegant way to access nested data from branches of the state that are only available part of the time?
I'm new to React and this problem keeps coming up. I have an ok grasp on Redux and using middleware like Thunk & Saga for the API stuff, but I still don't understand the proper way to write components so that they're not trying to grab non-existent state.
For example, when loading a user's profile photo into a header after the user signs in, the URL will be in the redux store as state.user.userData.photos.primary ...if I try to access that location when the user hasn't signed in, userData is still undefined and React will throw an error. So my solution has been to write assignments like:
let profilePhoto = props.user.userData ? props.user.userData.photos.primary : '';
... which seems cumbersome and inefficient, especially since it requires mapping the entire userData object in mapStateToProps only for the sake of accessing a tiny chunk of data.
I wish I could target it earlier. For example, in mapStateToProps:
profilePhoto : state.user.userData.photos.primary || '';
...but that results in "can't access 'photos' of undefined". So what's an efficient/elegant way to access nested data from branches of the state that are only available part of the time?
In your mapStateToProps access your state like this:
profilePhoto : state.user.userData ? state.user.userData.photos.primary : ''
and then use profilePhoto as props. This will not throw an error of undefined.
In my current application I initialize the redux state with all the data tree that I will use; so that I will unlikely end up with undefineds.
So a solution would be:
const initialState = {
userData: {
photos: {
primary: ""
}
}
}
This might look ugly in the first glance but it helps me keep track of what my data will look like, and can be simplified by defining parts of the object individually.
An alternative could be keeping a flag in the redux state like isUserPrimaryPhotoDefined which you would set to true when you are setting the primary variable; so you can use the flag in the ternary. However that might not guarantee getting rid of the possible errors completely.
With ES6 Destructuring Assignment, you can access nested keys from props in a cleaner way.
const { user: { userData: { photos: { primary = ''} = {}} = {}} = {}} = props;
console.log(primary); // prints primary value or '' if not defined
I want to ask the community about an ideological problem.
Lets imagine todo-list on react/redux, you have single state where todoItems array is served. But now lets imagine I want to have few components on the page that are render todoItems with different UI. And I need to update each these components on CRUD of todoItems. What is your architectural approach of this issue? Don't forget we have a large database and we can get todoItems with pagination only.
Update:
Lets make it clear. When we implement redux life cycle with this UI we have 2 options:
1) Serve one array of todoItems into singleton redux state object.
Advantages: all our components will updates by object changing.
Problems: we can't get ALL data from our database, but have to show different paginated/filtered data, so we can't implement pagination/filtering on frontend-side. We have a few different components and the have to render different objects collection. So it doesn't fit.
2) We can use different keys into our global redux state.
Advantages: we can independently get data for each component
Problems: other components will not feel when object changing in one of them. In this case we have to write custom code.
I just want to know maybe I'm missing something and we have other option or maybe someone have good architectural approach to this problem.
I bet your complications come from the point of view which unfortunately quite common among redux community: trying to keep redux shape as close to UI shape as possible.
Try no to think about redux state as a substitute for the Component states. What redux should know about is actual todos only (id, title, date of creation, etc.). Let Component-specific data like pagination stuff live in Components state. When user goes to next page in one of the Components what should be updated is this Component state (pageNumber, from, to, amount, etc.). redux should be updated only in case necessary todos are missing.
The useful analogy is to thinking about your redux as good old SQL-database: redux store state is data itself, selectors and actions are queries and stored procedures, React Components are views with selected data.
Update: Ok, seems like what you are looking for is state normalization. Separate todos details from the lists of ids. This way updates of todo fields will be sensed by all the Components. On the other hand you'll be able to keep separate collections of todos in different Components. Namely make state look like this:
{
funnyTodos: [ 'id1', 'id2' ],
boringTodos: [ 'id3', 'id4' ],
recentlyDoneTodos: [ 'id1' ],
todos: {
id1: { name: .... },
id2: { name: .... },
id3: { name: .... },
id4: { name: .... },
}
}
Implementing pagination in this case is just a matter of getting list of todos ids for the next page from back-end and then loading missing todos for given ids.
I am struggling a bit with the concept of global state and reusable components in redux.
Let's say I have a component that's a file-selector that I want to use in multiple places inside my applications state. Creating action/reducers leads to a lot of bloat as I have to handle states with dynamic suffixes and other weird things that just don't really strike me as a smart way to go about things.
What's the general consensus on these things? I can only see two solutions:
Make the file-selector component have local state (this.setState/this.getState)
Make the file-selector be part of the global state but in it's own unique reducer that I can read from once the operation of the component is done?
Any ideas / best practices? Thanks.
Update: To clarify the file selector I am describing is not a simple component that works purely on the client side but has to fetch data from the server, provide pagination as well as filtering etc.. That's why I'd also like to reuse most of the client/server interaction. The views that display this component are of course dumb and only display values from the state - but how do I reuse the actions/reducers in multiple places around the application?
Have your reducer handle multiple instances of your component state. Simply define some "unique" ID for each instance of your FileBrowser component when it appears in the app, and wrap your current state in an object with this uniqueIds as keys, and your old complex state as value.
This is a technique I've used multiple times. If all your FileBrowser are known at compile time, you can even setup the initial state before running your app. If you need to support "dynamic" instances, simply create an Action that initializes the state for a given id.
You didn't provide any code, but here's a contrived example for a reusable Todo reducer:
function todos(state={}, action){
switch(action.type){
case 'ADD_TODO':
const id = action.todoListId
return {
...state,
[id]: {
...state[id],
todos: [ ...state[id].todos, action.payload ]
}
}
// ...
}
}
Usually, the rule of thumb is that you use a redux store to manage data in your application aka storing items fetched from the server and local react state for ui behaviors, like file uploads in your case. I'd make a pure react component to manage file uploads and then use redux-form to manage specific form.
Here is the example of the component I use in my project
import React, {Component, PropTypes} from 'react';
import Button from 'components/Button';
class FileButton extends Component {
static propTypes = {
accept: PropTypes.string,
children: PropTypes.any,
onChange: PropTypes.func.isRequired
};
render() {
const {accept, children, onChange} = this.props;
return <Button {...this.props} onClick={() => this.file.click()}>
<input
ref={el => this.file = $(el)}
type="file"
accept={accept}
style={{display: 'none'}}
onChange={onChange}
/>
{children}
</Button>;
}
}
export default FileButton;
We came to the conclusion that reusable components must be of two kinds:
dumb components, i.e. components that only receive props and trigger "actions" via props callbacks only. These components have minimal internal state or at all. These are the most frequent of reusable components, and your file selector will probably fall in that case. A styled Text Input or custom List would be good examples too.
connected components that provide their own actions and reducer. These components have their own life within the application and are rather independent from the rest. A typical example would be a "top error message box" that displays on top of everything else when the application fails critically. In such a case the application triggers an "error action" with the appropriate message as payload and on the following re-render, the message box displays on top of the rest.
I'm coding an application using React for UI, Redux to manage the state and Immutable.js to mutate the state, however, I'd like to know how to avoid the use of Immutable.JS accessors in my React components, like get() or getIn().
I believe that using that Immutable.JS accessors will infect my React components. How to avoid that?
I don't think you're going to have much in the way of an option here if you want to keep it immutable. You could convert it toJS, but then you'd be losing the benefits of object identity comparison for re-rendering pure components. Your best bet is probably to hold your nose and pretend it's basically a JavaScript Map.
Aside from that, if you're not attached to Immutable.js, you might consider using something like seamless immutable which behaves a lot more like native JavaScript arrays and objects. Or you could go old-fashioned and just Object.freeze() things yourself.
The way to avoid Immutable.JS accessors and use the dot-notation is using the Record structure from Immutable.JS.
First we must create a template:
const MyTemplate = Record({
id: 0,
name: ''
})
...
case ContentFilterTypes.ADD_ITEM:
return {
listObjects : state.listObjects.push(new MyTemplate({
id: action.item.id,
name: action.item.description,
}))
}
To access it in the presentional, we need only to set the prop that we want to get information, like:
<ContentFilterAvatar id={value.id} name={value.name} />