how i convert this to functional component in react native - react-native

let { eventDate } = this.state;
if (eventDate <= 0) {
this.setState({ isTimerOver: true});
}
Here I need to write this in functional components. can you help me to do this

You can use useState hook in functional component
import { useState } from 'react';
...
const yourFunctionName = () => {
const [ eventDate, setEventDate ] = useState(0) // set initial value here
// The first value eventDate , is our current state.
// The second value setEventDate, is the function that is used to update eventDate state
const [ isTimerOver, setIsTimerOver ] = useState(false) // set initial value
...
if (eventDate <= 0) {
setIsTimerOver(true); // function to update the state isTimerOver
}
...
}
export default yourFunctionName;
Refer this : React useState Hook

Related

React native changing instance prop not rerender component

I have an entity class called order
const order = new Order({status: 'available'});
export default class Order {
constructor({status}) {
this.status = status;
}
isCanceled() {
return this.status === CANCELED;
}
}
when passing order to a component throw mapStateToProps
when the status changes. mapStateToProps will be called again with the new status but the component will not be rendered with the new data
but if I passed the order as a standard object it will re-render with the new data
This code is not working
const mapStateToProps = (state, props) => {
const order = new Order({status: 'available'});
return {
order,
};
};
This code works
const mapStateToProps = (state, props) => {
const order = new Order({status: 'available'});
return {
order: {...order},
};
};
I need the first code to work as I use some functions from the object inside the component like isCanceled()
Hello all I knew what was the issue
the problem was in my reducer as I was changing in the state directly so the method wasn't pure function. So, react didn't recognize the change in props
this link has an example
React Native components not re-render if props changed
can you try this, while keeping the {...order} (2nd method you're using)
export default class Order {
constructor({status}) {
this.status = status;
this.isCanceled = this.isCanceled; //add this line
}
isCanceled() {
return this.status === CANCELED;
}
}

observable and computed not being reflected in a functional component

I am learning mobx for react-native and not able to see changes to done to observables or computed.
Basically, I want to listen to changes to observable from the component.
My store is simple:
import { observable, action, computed } from 'mobx';
import AsyncStorage from '#react-native-async-storage/async-storage';
class ConfigStore {
rootStore = undefined;
#observable activeConfig = {group: 'starter', TC: false};
constructor(rootStore) {
this.rootStore = rootStore;
}
#computed get termsLoaded(){
return this.activeConfig.TC;
}
#action async loadPreviousConfig() {
const configDetails = { group: 'starter', TC: false};
try {
const response = await AsyncStorage.multiGet([
'group',
'TC'
]);
configDetails.group = response[0][1] || 'starter';
configDetails.TC = response[1][1] === undefined ? false : true;
console.log(configDetails);// shows correct previously saved config
this.activeConfig = configDetails;
} catch (error) {}
}
}
export default ConfigStore;
From my component, I want to load first previous configuration settings and have them reflect in my app. Basically, I want to check the value of TC ater calling loadPreviousConfig, they return false still:
import { inject, observer } from 'mobx-react';
const ConfigComponent = (props) => {
const { store } = props;
const { termsLoaded, activeConfig, loadPreviousConfig } = store.configStore;
useEffect(() => {
const init = async () => {
await loadPreviousConfig();
console.log(termsLoaded); //always false even though console from the store shows it is true.
};
init();
}, []); //tried [props]
return (
<View>
<Text>{activeConfig.group}</Text> //never changes
</View>
);
};
export default inject('store')(observer(ConfigComponent));

Mobx React Reactivity with Hooks and Observer

I've updated the app to use Mobx-react 6 along with Mobx state tree.
I'm not able to get the latest value inside the component when I use custom store hooks.
import { observer, MobXProviderContext, useObserver } from 'mobx-react';
function useStores() {
return useContext(MobXProviderContext);
}
function useJob() {
const { jobStore } = useStores();
return useObserver(() => jobStore);
}
//USAGE
function ChildDocs(props) {
const jobStore = useJob();
const { validChildDocuments, setCurrentChildDoc, currentChildDoc, noneDocuments } = jobStore;
//This won't update although the value in the store is null after re-mount. This shows the old value
console.log('verificationDataStore=', currentChildDoc.verificationDataStore);
}
export default observer(ChildDocs);

Redux action updates the state, but it then immediately reverses itself to null?

I'm trying to pick a random object out of a collection, and update the state with it's values; it's all being done in redux. The problem that I'm running into is that I get my random object, but as soon as the action completes, the state goes back to null. Here's what I'm doing:
1) I created an action file with one function. As soon as the app's button is clicked, this action is triggered.
import { mapData } from '../../mapData';
export const getRandomMap = (mapPlayerCount) => dispatch => {
// get a collection of 1v1, 2v2, 3v3, or 4v4 maps based on the map player count
const maps = Object.values(mapData).filter(map =>
map.players === mapPlayerCount
);
const min = 0;
const max = maps.length;
const randomIndex = Math.floor(Math.random() * (max - min + 1)) + min;
dispatch({ type: 'GET_RANDOM_MAP', randomMap: maps[randomIndex] });
}
2) Dispatch takes me to the reducer file that updates the state.
const INITIAL_STATE = {
randomMap: null
};
const mapReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case 'GET_RANDOM_MAP': {
return {
...state,
randomMap: action.randomMap
};
};
default: {
return state;
};
};
};
export default mapReducer;
3) And this is the actual screen with the button, that triggers the action (truncated unrelated code)
import { getRandomMap } from '../redux/actions/map_actions';
import { connect } from 'react-redux';
class RandomMapPickerScreen extends Component {
state = {
...
}
handleSelection = (selectedIndex) => {
...
}
handleRandomMapRequest = () => {
switch (this.state.selectedIndex) {
case 0: {
// 2 player maps / 1v1
this.props.getRandomMap(2);
break;
}
case ...
}
console.log(this.props.randomMap)
//this.setState({ showPropThumbnail: false })
}
render() {
...
}
}
const mapStateToProps = state => ({
randomMap: state.map.randomMap
});
export default connect(mapStateToProps, {
getRandomMap
})(RandomMapPickerScreen);
const styles = StyleSheet.create({...});
Let me walk you through what I see in the debugger:
1) I click the button, and it takes me to the action
2) The app goes through all the reducers, and correctly updates the state with the new randomMap value
3) It then takes me back to the screen file, and I can clearly see randomMap with correct value
4) The dispatch is done in my actions file
5) The code takes me back to the main screen file, however this time, randomMap is at the default NULL value... Why is this happening? Shouldn't my randomMap keep the value?
Are you trying to view the contents of a prop immediately after the action has been dispatched? If so, React hasn't had a chance to re-render the component yet, so the prop will still have the old value.
This is very similar conceptually to trying to view the contents of a state change right afterwards, like:
// assume it's previously {a : 1}
this.setState({a : 42});
console.log(this.state.a) // 1, not 42
Because setState() is normally async.

How to use a custom reducer's state as a permanent filter in a <List>?

I have a custom reducer and a connected component to change its state. Now I'd like to use this state as a permanent filter on List elements.
I understand the List elements are connected to the redux-state, so I hope I'm able to access it through the List component's props, but couldn't find a way how to do that.
The List component is connected but not yours.
import { connect } from "react-redux";
const MyList = ({ is_published, ...props }) => (
<List {...props} filter={{ is_published }}>
</List>
);
const mapStateToProps = state => ({
is_published: state.myCustomReducer.is_published,
});
export default connect(mapStateToProps, undefined)(MyList);
Edit:
Just found out we don't update data when this prop change. This is a bug and you can open an issue about it.
In the mean time, here's a workaround:
Create a custom saga listening to whatever action you use alongside your custom reducer (I'll call it SET_IS_PUBLISHED for my example). This custom saga should put the changeListParams action creator from react-admin with your filter.
It will probably looks like this (not tested):
import { takeEvery, put, select } from 'redux-saga/effects'
import { changeListParams } from 'react-admin'
import { SET_IS_PUBLISHED } from './isPublished'
const getCurrentListParams = (state, resource) => {
const resourceState = state.admin.resources[resource]
return resourceState.list.params
}
function handleSetPublished({ payload }) {
const currentParams = yield select(getCurrentListParams)
const newParams = {
// Keep the current params
...currentParams,
// Override the filter
filter: {
// Keep the current filter
...currentParams.filter,
// Only override the is_published
is_published: payload
}
}
// Dispatch the action for the `posts` resource
yield put(changeListParams('posts', newParams))
}
export default function* () {
yield takeEvery(SET_IS_PUBLISHED, handleSetPublished)
}
just to bring this into 2021, you can use the useSelector redux hook to get hold of your custom state:
import { useSelector } from 'react-redux';
const MyCustomThing = (props) => {
const is_published = useSelector(state => state.customState.is_published);
}
For completeness, react-admin provides a customReducers prop to its <Admin> component so you can extend the redux state with your custom values:
const customStateReducer = (customState = { is_published: false }, { type, payload }) => {
if (type === 'IS_PUBLISHED') customState.is_published = payload.is_published;
return customState;
}
<Admin customReducers={{ customState: customStateReducer }} ...>
etc