0

My idea is that when someone put a text in my TextInput and clicks submit then botToc() will save the data from that API search in result and show the result in a FlatList.

But I have a problem saving data with hooks. The thing is that my setResult is not working properly because it does not save well the data from the API query. botToc() is supposed to fetch data from an API and its doing that fine but then I loop through the fetched data and I save what I want in result using setResult.

The thing is that when I click the button that uses botToc2() ( after clicking the button that uses botToc() ) my console.log(result) shows only the data of the last element and if I use again botToc() and I click one more time botToc2() I get that last element duplicated in the result array.

How can I fix this?

export default function TestScreen () {

    const [querypar, setQuerypar] = useState('');
    const [apipar, setApipar] = useState('https://API/search?q=');
    const [result, setResult] = useState([]);

    const ItemView = ({item}) => {
      return (
          <View>
            <Text>
              {item[0]+ '  ' + item[1]}
            </Text>
          </View>
      );
    };

   function botToc() {
      let query = apipar+querypar;  //'https://API/search?q='+'TextInputText'
      let cargador = [];

      fetch(query) //'https://API/search?q=TextInputText'
      .then( res => res.json() )
      .then( res => {
        // (res.results) = [{price:x,title:x},{price:x,title:x},{price:x,title:x}] structure of (res.results)
        (res.results).forEach( (element) => {
            cargador.push(element.title);
            cargador.push(element.price); //cargador=[x,x]
            setResult([...result, ...cargador]); //result=[[x,x],[x,x]...]
            cargador.length = 0; //cargador=[]
        });
      })
   };


   function botToc2() {
    console.log(result); //my console should return [[x,x],[x,x],[x,x],[x,x],[x,x],[x,x],...]
   };

    return (
      <View View style={styles.container}>
        <TextInput placeholder="write here" onChangeText={(val) => setQuerypar(val)} />
        <View>
            <Button onPress={botToc} title="Submit"/>
            <Button onPress={botToc2} title="Submit"/>
            <FlatList
            data={result}
            renderItem={ItemView}
            keyExtractor={(item, index) => index.toString()}
            />
        </View>
      </View>
    );
};

1 Answer 1

2

Calling setResult() multiple times in the forEach function should be avoided. In that case your botToc() function should look like this:

    function botToc() {
      let query = apipar+querypar;  //'https://API/search?q='+'TextInputText'
      let cargador = [];

      fetch(query) //'https://API/search?q=TextInputText'
      .then( res => res.json() )
      .then( res => {
        // (res.results) = [{price:x,title:x},{price:x,title:x},{price:x,title:x}] structure of (res.results)
        (res.results).forEach( (element) => {
            cargador.push([element.title, element.price]); //cargador=[x,x]
        });
      })
      setResult(cargador);
   };

This should do the job for you.

Sign up to request clarification or add additional context in comments.

2 Comments

Well that did the job but why cant i call setResult() multiple times? Whats the logic behind?
@knownothingjonsnow , you can call setResult() multiple times but this is not a good practice in React, because each time a state is set, the component get re-rendered. So, multiple setState call should be avoided. And, in case of your error, I think you did not get the error for the setResult() call. Rather it was for the syntax inside the setResult([...result, ...cargador]) call.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.