I have a form which includes a select dropdown (items are populated via an api call). When I leave the screen I would like to be able to reset this back to it's initial state (Default state is a placeholder - Select Event)
I can clear text and textarea inputs within a useFocusEffect() but struggling with understanding how to reset a select dropdown
To reset the select dropdown i have tried setEventTypeData([]); but when navigating back to the screen, the last selected option is still selected (text inputs have been cleared though)
export const CreateNewEvent = ({navigation}) => {
const globalContext = useContext(AppContext);
const userId = globalContext.userInfo.id;
// dropdown populated with this
const [eventTypeData, setEventTypeData] = useState([]);
const [newEventDescription, setEventDescription] = useState('');
const [newEventLimit, setEventLimit] = useState(0);
const clearFormData = () => {
setEventTypeData([]); // tried setting back to original state but does not work
setEventDescription('');
setEventLimit(0);
};
useFocusEffect(
React.useCallback(() => {
const body = JSON.stringify({userId});
fetch(eventTypesUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: body,
})
.then(response => response.json())
.then(json => setEventTypeData(json))
.catch(error => console.error(error))
.finally(() => setLoading(false));
return () => {
// Run logic when the user leaves screen,
// Clear form
clearFormData();
};
}, [userId]),
);
// Select Dropdown
{/* Event Name Select Field */}
<FormControl isRequired isInvalid={'eventName' in errors}>
<FormControl.Label>Select Event</FormControl.Label>
<Select
onValueChange={newEventName =>
updateEventNameAndDescription(newEventName)
}
placeholder="Select Event"
{eventTypeData.map(event => (
<Select.Item
key={event.id}
label={event.name}
value={event.name}
/>
))}
</Select>
}
How can i ensure that when navigating back to this screen that the Select dropdown is reset to its original state
Thanks
I rewrite your example. I hope this help. You forget to unsubscribe
from API call
import { useIsFocused } from '#react-navigation/native';
const isFocused = useIsFocused();
useEffect(() => {
if (!isFocused) {
clearFormData()
}
}, [isFocused]);
useFocusEffect(
React.useCallback(() => {
const body = JSON.stringify({ userId });
const unsubscribe = fetch(eventTypesUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: body,
})
.then((response) => response.json())
.then((json) => setEventTypeData(json))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
return () => unsubscribe();
};
}, [userId]),
);
export const CreateNewEvent = ({navigation}) => {
const globalContext = useContext(AppContext);
const userId = globalContext.userInfo.id;
// dropdown populated with this
const [eventTypeData, setEventTypeData] = useState([]);
const [newEventDescription, setEventDescription] = useState('');
const [newEventLimit, setEventLimit] = useState(0);
const [selectedEventName, setSelectedEventName] = useState();
const clearFormData = () => {
setSelectedEventName();
setEventDescription('');
setEventLimit(0);
};
useEffect(() => {
selectedEventName ? updateEventNameAndDescription(selectedEventName) : clearFormData();
}, [selectedEventName])
useFocusEffect(
React.useCallback(() => {
const body = JSON.stringify({userId});
fetch(eventTypesUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: body,
})
.then(response => response.json())
.then(json => setEventTypeData(json))
.catch(error => console.error(error))
.finally(() => setLoading(false));
return () => {
// Run logic when the user leaves screen,
// Clear form
clearFormData();
};
}, [userId]),
);
// Select Dropdown
{/* Event Name Select Field */}
<FormControl isRequired isInvalid={'eventName' in errors}>
<FormControl.Label>Select Event</FormControl.Label>
<Select
value={selectedEventName}
onValueChange={newEventName =>
setSelectedEventName(newEventName)
}
placeholder="Select Event"
{eventTypeData.map(event => (
<Select.Item
key={event.id}
label={event.name}
value={event.name}
/>
))}
</Select>
}
If you're using React Native Picker or something related, That picker is bound to the device native Select component, This has more performance benefit as it's not run on JavaScript thread, React rerendering will not affect that component.
But in this situation, we need to force this component to unmount when the user leaves the screen or mount when the screen is focused.
// Top-level import
import { useIsFocused } from '#react-navigation/native';
// Inside functional component
const isFocused = useIsFocused();
// Force <Select> to unmount or mount when screen focused
{ isFocused && <Select
value={selectedEventName}
onValueChange={newEventName =>
setSelectedEventName(newEventName)
}
placeholder="Select Event"
{eventTypeData.map(event => (
<Select.Item
key={event.id}
label={event.name}
value={event.name}
/>
))}
</Select>}
I try page isfocused work this method.this is working and go to getuserform method.But Axios
does not request again.I can't see any response or exception.I get old data again.
useEffect(() => {
dispatch(getUserForm(id))
}, [id, isFocused])
export const getUserForm = (userId) => {
return dispatch => {
axios.get(`${APIURL}/Form/${userId}`)
.then(response => {
dispatch({
type: 'GET_USER_FORM',
userForm: response.data,
})
})
.catch(err => console.error)
}
}
i'm trying to list some products. i want to get categoryName as title by navigation, well if i put that line in render it works but i need to use it in componentDidMount how can i do that? is there any suggestions?
there is some part of my code
export default class ProductList extends React.Component {
navigation = this.props.navigation;
constructor(props) {
super(props);
this.state = {
isData: false,
};
}
componentDidMount() {
const title = navigation.route.params.categoryName; //here is my problem
fetch(global.apiPost + global.token, requestOptions)
.then((response) => response.json())
.then((result) => {
result.forEach((element) => {
if (element.Menu === title) {
products.push(element);
}
});
this.setState({isData: true});
})
.catch((error) => console.log('error', error));
}
put a check in componentDidMount
componentDidMount() {
if (navigation?.route?.params?.categoryName){
const title = navigation.route.params.categoryName; //here is my problem
fetch(global.apiPost + global.token, requestOptions)
.then((response) => response.json())
.then((result) => {
result.forEach((element) => {
if (element.Menu === title) {
products.push(element);
}
});
this.setState({isData: true});
})
.catch((error) => console.log('error', error));
}
}
I am new on React Native, somethings could be wrong in my code.
I want to check API every 10-sec. The code should be okay but I don't understand why it responds more than once every time when the Backgroundtimer calls.
const App = () => {
const [isLoading, setLoading] = useState(false);
const [data, setData] = useState([]);
useEffect(() => {
fetch('http://192.168.2.131/api/QChatTrakan?templateNo=22')
.then((response) => response.json())
.then((json) => setData(json))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, [reflesh]);
BackgroundTimer.runBackgroundTimer(() => {
fetch('http://192.168.2.131/api/QChatTrakan?templateNo=22')
.then((response) => response.json())
.then((json) => setData(json))
.catch((error) => {
console.error(error);
});
console.log(data);
},
10000);
enter image description here
You can check the below code for call function or fetch API every 10 seconds.
const callAPi = () => {
console.log('callAPi initial',new Date().toLocaleString())
setInterval(() => {
console.log('callAPi',new Date().toLocaleString())
},10000)}
useEffect(() => {
callAPi()
}, [])
I'm fetching JSON Data within componentWillMount() from my "Scanner" component like so:
async componentWillMount() {
const url = 'https://foo.com/products/product1.json';
fetch(url)
.then((response) => response.json())
.then((responseData) => this.props.dispatchProductLoad())
.catch(error => {
console.log(error);
});
}
And below is my dispatch code:
function mapDispatchToProps(dispatch) {
return { dispatchProductLoad: () => dispatch(productLoad(SOMEDATA)) };
};
export default connect(null, mapDispatchToProps)(Scanner);
Where the variable SOMEDATA should hold the value from responseData (at the moment it's not defined)
So my question is - how do I set the value of SOMEDATA to the value held in responseData?
You would call the action creator with the responseData as an argument and define your mapDispatchToProps function like
async componentWillMount() {
const url = 'https://foo.com/products/product1.json';
fetch(url)
.then((response) => response.json())
.then((responseData) => this.props.dispatchProductLoad(responseData))
.catch(error => {
console.log(error);
});
}
function mapDispatchToProps(dispatch) {
return { dispatchProductLoad: (response) => dispatch(productLoad(response)) };
};
export default connect(null, mapDispatchToProps)(Scanner);