Home > database >  map() does not return anything
map() does not return anything

Time:11-02

In a button onClick I have a function that makes a GET petition and recieves a json array. When I try showing that to the user, nothing changes, although if I put a console.log inside the map I does show and iterate though all the objects.

fetch('http://localhost:3000/GetApunte',{
            method: 'GET',
            headers: {
                Accept: 'application/json',
                'Content-Type': 'application/json'
            }
        })
        .then(response=>response.json())
        .then(responseJson => {            
            this.datosCargados=true;
            this.anotaciones=responseJson;
            //cuerpo()
            
                return(
                    <tbody>
                        {this.anotaciones.map((anotacion, index)=>{
                            const {titulo, body} = anotacion
                            return(
                                <tr key={index}>
                                    <td>{titulo}</td>
                                    <td>{body}</td>
                                </tr>
                            )
                        })}
                    </tbody> 
                );
        });

The structure of my class is like this:

export default class Apuntes extends React.Component{
state ={}
getApuntes(){}

render(){
    return(
        <button onClick={()=> this.getApuntes()}>Mostrar Apuntes</button>
    )
}
}

The anotaciones is inside the state, thats why I use this.anotaciones

CodePudding user response:

You can not simply return data from a promise directly into React component as it would not be easy to control dataflow state between an async function and a synchronous component. Try following this pratice:

const [arr, setArr] = useState([]) // array empty on init
async fetch() {
    return fetchedArray; // get array from remote 
}

useEffect(() => {
   fetchdArray().then(fetchedArr => setArr(fetchedArr);
}, []); // this is equal to componentDidMount in class component

return (<div>{arr.map(...)}</div>)

By this way the arr is always updated its state to the screen, from empty until populated

CodePudding user response:

Instead of returning the JSX in the promise, just save anotaciones into a the state. You can extract the generation of the table into a separate function, like

const generarAnotaciones = () =>
    <tbody>
        {this.anotaciones.map((anotacion, index) => {
            const { titulo, body } = anotacion
            return (
                <tr key={index}>
                    <td>{titulo}</td>
                    <td>{body}</td>
                </tr>
            )
        })}
    </tbody>

Then your class should be something like this:

export default class Apuntes extends React.Component {
    state = {}
    getApuntes() { }

    render() {
        return (
            <>
                <button onClick={() => this.getApuntes()}>Mostrar Apuntes</button>
                {generarAnotaciones()}
            </>
        )
    }
}
  • Related