how to use the api data res with hooks - reactjs

Hi i know this question its a little dumb but im learning to use react native with hooks and some things give me troubles to understand.
I have this api call with axios
const getRFC = ({vLastName,vSecondLastName,vName,vSecondName,vBirthDate}) => {
axios. post(`http://exitusdesarrollo.eastus2.cloudapp.azure.com/AppForceControllers/controllers/GetRfcController.php`, { vName, vSecondName, vLastName, vSecondLastName, vBirthDate })
.then(res => {
console.log(res.data.resultRFC);
})
}
and yeah in console log prints what i need, so what i dont know how to do it is how to use the res.data.resultRFC outside the function.
normally it would be something like
`const RFC= res.data.resultRFC;
this.setState({ RFC});`
but since im using hooks this throws me error, any advice?

use useState inside your function:
import React, { useState } from 'react';
// inside your component
const [rfc, setRfc] = useState(null);
// inside your axios callback
setRfc(res.data.resultRFC);
// later in your component / render you can use rfc
{rfc && <Text>{rfc}</Text>}
for more reference: https://reactjs.org/docs/hooks-state.html

Related

What is the best practice for useAxios hook with Redux's slice?

I've created a useAxios hook to use for Axios calls and also reduxjs/toolkit for handling React data. Is it the correct practice to use them together?
For example, in slice.js
export const getTodo = (data) => async (dispatch) => {
try {
const response = await axios.get(`${URL}/${data}`);
dispatch(getTodo(response.data));
} catch (err) {
throw new Error(err);
}
};
When I replace await axios.get(`${URL}/${data}`); to useAxios()hook, I got the error: hooks can only be called inside of the body of a function component.
What is the best practice for Redux to use the Axios hook? or it's not possible? Any good example? Thanks!
*The only place you can ever call a React hook is inside of a function component, or another hook. You can never call a hook anywhere else.

Is it possible to use i18n localization for redux Actions?

I was trying to implement i18n localization for Redux Action functions, but i constantly recieve different hook errors. When i implemented i18n this way i recieve error.
Line 428:17: React Hook "useTranslation" is called in function "sendDataRequest" that is neither a React function component nor a custom React Hook function.
import { useTranslation } from "react-i18next";
export const sendDataRequest = (requestId) => {
const { t } = useTranslation();
return async (dispatch) => {
try {
dispatch(sendDataRequest());
await dataAPI.sendDataRequest({ requestId });
notification.success({
message: t('infoPage.requestSentSuccessfully'),
});
dispatch(sendDataSuccess());
} catch (error) {
dispatch(sendDataFailure());
console.error(error);
}
}
}
Then i moved const { t } = useTranslation(); inside of return statement.
But then i recieved another error
It looks like I obviously using it wrong here.
But i cannot find any examples on i18n being used in Actions.
Does anyone knows is it even possible to use i18b in Actions?
Check out https://github.com/i18next/react-i18next/issues/909
You need to gain access to your i18next instance. The one you create somewhere in your codebase. With this instance you can simply call i18n.t("my.translation.key") to translate. This is completely independent from react.

How to make Jest test for hook without UI

I have the next hook
const useFetch => {
let { state, dispatch } = useContext(AppContext);
const fetch1 = async () => {
...code to fetch data (mocked)
}
const fetch2 = () => {
...
}
return {
fetch1,
fetch2,
...
};
};
export default useFetch;
I need to create jest test but i can't do it directly because it break the rules of hooks, and I can't render it because it not have UI to render, it's only fetch data to store to the context.
Can anyone help me to understand how to do it?
Thanks in advance and sorry for my english.
You could create a wrapper component for test purpose only and work with that. However Testing Library has a great tool for that, hooks-testing-library. It might be a good addition to your project if you have more hooks to test.

ReactJS: Pass object into fetch promise

I'm kind of new react, and this quill plugin is really confusing me. I'm using react-quilljs to display an editable rich text field, which is supposed to be pre-populated with a value retrieved using fetch from my API. Seems pretty simple, right? But I'm getting the error 'quill is undefined' in the fetch callback.
import React, { useState, useEffect } from "react";
import { useQuill } from "react-quilljs";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
// see https://www.npmjs.com/package/react-quilljs
export default function View(props) {
const [group, setGroup] = useState([]);
const { quill, quillRef } = useQuill({});
useEffect(() => {
fetch('/api/groups/' + props.id , {
method: 'GET'
})
.then(res => res.json())
.then((data) => {
setGroup(data);
quill.setContents(JSON.parse(data));
})
.catch(console.log);
}, [quill]);
return(
<div >
<div id="descriptionInput" ref={quillRef} />
</div>
);
}
Of course I've omitted a lot of the code, but I think it should be enough to illustrate the problem. I think, basically the question is, how do I pass the quill object into the fetch promise?
I have searched for the answer but for some reason can't find anything on this.
I looked through the documents and found this:
quill.clipboard.dangerouslyPasteHTML();
I have made a working sample for you:
https://codesandbox.io/s/epic-stonebraker-itt06?file=/src/App.js:401-469
After some more inspection, it turns out useEffect is being called multiple times, and quill is not available right away (as Asher Lim notes). So adding a check if (quill) inside the fetch promise solves the problem.
Of course this means that the fetch is being done more times than necessary, which can be solved with some more refactoring.

React useEffect inside const function with MobX

I have some React Redux code written in Typescript that loads some data from my server when a component mounts. That code looks like this:
import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { MyAction } from 'my/types/MyAction';
export const useDispatchOnMount = (action: MyAction) => {
const dispatch = useDispatch();
return useEffect(() => {
dispatch(action);
}, [dispatch]);
};
This is simple enough - it uses the useEffect hook to do what I want. Now I need to convert the code so that it uses MobX instead of Redux for persistent state. If I have my own MobX store object called myStore, and myStore has a async method "loadXYZ" that loads a specific set of data XYZ, I know I can do this inside my component:
useEffect(() => {
async functon doLoadXYZ() {
await myStore.loadXYZ();
}
doLoadXYZ();
}, []);
This does indeed work, but I would like to put all this into a single fat arrow function that calls useEffect, much like what the useDispatchOnMount function does. I can't figure out the best way to do this. Anyone know how to do this?
EDIT: After further digging, it looks more and more like what I am trying to do with the Mobx version would break the rules of Hooks, ie always call useEffect from the top level of the functional component. So calling it explicitly like this:
export const MyContainer: React.FC = () => {
useEffect(() => {
async functon doLoadXYZ() {
await myStore.loadXYZ();
}
doLoadXYZ();
}, []);
...
};
is apparently the best way to go. Butthat raises the question: is the redux version that uses useDispatchOnMount a bad idea? Why?
You can do this if you don't use async/await in the useEffect. If you are fetching data, I would store it in myStore and use it directly out of the store instead of using async/await. It might look something like this:
export const SomeComp = observer(function SomeComp() {
const myStore = useStore() // get the store with a hook or how you are getting it
useEffect(myStore.loadXYZ, [myStore])
return <div>{myStore.theLoadedData}</div>
})
In loadXYZ you just store the data the way you want and use it. The component observing theLoadedData will re-render when it comes back so you don't need to have async/await in the component.

Resources