I am using react native.
Here's my code.
function mapStateToProps(state) {
return {
markers: state.markers,
};
}
I set props using mapStateToProps and it only called when I dispatch an action.
I can set state using setState({..}); like this.
Here's my question.
How can I set props? Is there anything like setProps({..})?
It seems like you're using Redux. If you do, make sure to have both reducer and action scripts. The reducer is used to get a value from a specific state property or properties.
You have to define a function in your action script to assign or set a value to your specific state property and properties. You also need a store to bring both reducers and actions together.
The store initializes everything and allows you to dispatch actions and set or get values.
Two common ways of passing the props.
From Redux Store
Like what you have done in your code.
From other Components
Props can be passed by
<Foo prop1={bar} />
And in your Foo Component the props of prop1 is whatever bar is.
Related
I need to re-render this state manually.
const [person] = React.useState(new Person());
I have methods inside the Person class to update it (e.g. person.setName('Tom')).
When I update person using a method from itself, it does not trigger a re-render on the person state.
const carouselData = React.useMemo(() => {
// Doesn't re-render when the fields on the person class update
}, [person]);
Is there a way to force this state to re-render without using a setState function?
Ideally, is there a way to call that re-render from inside the Person class itself?
Or is this totally misusing the useState functionality? Would there be a better React hook to connect this to?
Thanks!
Person could be a prop or in context instead. First create your instance outside of your component.
const person = new Person([]);
Then pass person as a prop.
function App({person}) {
const [personName, setPersonName] = useState(person.personName);
function handleNameChange(txt) {
person.addTodo(txt);
setPersonName(person.personName);
}
function handleSubmit(txt) {
handleNameChange(txt);
}
return (...)
}
you are indeed miss using it, react relies heavy on functional programming. you should be doing something like:
const [person, setPerson] = useState(new Person());
...
setPerson(setPersonName(person, 'Tom'));
that's just a silly example but you get the gist. react will only re-render if state is changed, it won't monitor if the state object is mutating or anything like angularjs used to do
I have a quite decent background in android but now I am starting digging into react native and I am really confused with the ways to change the state of a component through hooks and set state function.
To the point, I have my main screen and I have many small components which change visibility. This is done by letting the user change some filter settings within dialogs. So the suggested way to do that is by having a hook in my main screen with a list that holds the values for the visibility of each component. But since I change the visibility of the components from inside the modals, every time I want to show a modal I will have to pass in a different function(for example setComponentEnable or setComponentDisabled) to set the state for each component. So my main screen will be polluted from all these small functions. Also I should not forget to mention that my modals are consisted from many smaller components and I will have to pass as deep as it goes the proper function to match the user action.
So my question is, is there a way to do this thing without polluting my main with all these small functions and make it possible for the main screen to update every time the user change the filters within the modals?
I already read about context but the docs say:
Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.
So I dont think that this should be a great case for context use.
What I am trying to do now is create a hook with a list
const [isibility, setVisibility] = useState([]);
create visibility handler functions
const setVisibilityEnable = () => {
...
}
and pass it into my modal.
<MyModal
visibilityHandler={setVisibilityEnable}/>
Is there a way to manipulate the state without passing all these callbacks to the modals? Or maybe is there anyone that can suggest a better and clean solution to avoid end up having a really huge main screen?
you can include all the settings in one object and pass that object to all the components. Then each component will then modify that object accordingly.
const defaultVisibility = {
childComponentOne: true,
childComponentTwo: true,
};
const [visibilityObject, setVisibilityObject] = useState(defaultVisibility);
pass both the function and the object into your child components:
<ChildComponentOne visibilityObject={visibilityObject} setVisibilityObject={setVisibilityObject} />
Then in your child component, you set the visibility like so:
setVisibilityObject({...visibilityObject, childComponentOne: false});
Why you don't just pass a property to your modal and check if changed in oncomponentdidchange method?
componentDidUpdate(prevProps) {
if (this.props.yourPoperty!== prevProps.yourPoperty) {
//do your visibility stuff
}
}
Alternatively you can do it with redux when you connect your components to the store.
I'm working on an app in React Native, and am having trouble accessing props that I feed into a component I made.
If I do console.log(this.props) within the constructor, I can see the props display in the console as desired, however if I put it in any other method, it prints undefined. How can I access the props that are clearly being sent to the component from outside of the constructor method?
You are probably adding new methods that are not binding this.
Check if you are writing the method like this:
myMethod(){
//Code
}
and just change it to:
myMethod = () => {
//Code
}
Edit: Like #Li357 says, these are called arrow functions. Arrow functions don't bind this automatically, and as a consequence receive the this of the surrounding class. In your case it will solve your issue as you want to access the properties of that class but you might want to read about it and how binding works in JS classes.
Another option is to write function.bind() but either way should work.
I am using react-native and react-redux to create a simple app. Thus, all of my props are passed in from mapStateToProps, coming from redux.
I should have to use mapDispachToProps to manipulate the props but that is not what is happening.
I have an event handler that allows me to directly manipulate the props. Why is this behavior occurring?
nameHandler(text) {
console.log(this.props.group.name); //output: Billy
this.props.group.name = 'illegal!';
console.log(this.props.group.name); // output: illegal!
}
I am binding 'this' to 'nameHandler' within the constructor, but that doesn't seem relevant.
I've mostly gotten around this, but shouldn't this not be possible?
I`m using Redux on react-native with redux and react-redux. I use combinereducers() to combine two reducers:
const reducers = combineReducers({
sessiontype,
userdata
})
Now I subscribe to some change in my reducers:
store.subscribe((state, previousState) => {
//Do something
});
How I subscribe only to my userdata reducer? Because when I change the state of my sessiontype reducer I need to change the state of my userdata reducer (and It create a infinite cycle in my store.subscribe() because detect the whole reducer has modified.... (sorry my bad english)
The concept around Redux is that you have only one state and one reducer. The idea that you have separate reducers is just an implementation detail introduced by combineReducers() - it allows you to think of your reducers in parts, but to your application there's simply one reducer. Check out the discussion on this GitHub thread.
The mapStateToProps function inside the react-redux package allows you to select what parts of a reducer a component has access to. This may help you solve your issue. When a component with access to sessiontype updates the reducer, you can have that same component update userdata. To do that, you simply dispatch two separate actions to the store. Also, remember that subscribe does not actually give you access to the store - it simply let's you know that something has changed. Inside your subscribe function, you need to call getState() to actually read the data. Read more here.
Try something like this:
store.subscribe((state, prevState) => {
// run a check of conditions for an action being dispatched
// if you don't specify conditions, you'll end up in an
// infinite loop
if (stateHasFieldOrValue) {
// dispatch update to sessiontype
store.dispatch(updateSessionType(payload));
// dispatch update to userdata
store.dispatch(updateUserData(payload));
}
});