1

I am very new to Reactjs. I am taking a course in Reactjs and trying by myself. So kindly excuse me.

  1. In the below code I have two list boxes. I am selecting the postcode and based on the post code the other list box needs to be populated
  2. In order to achieve this I used useEffect but made sure I passed empty array at the end so that it will not be called every time the state data and pc are updated
  3. I read the other similar post and did #2.
  4. Clearly the renders are in loop but which one?
  5. I see many questions similar to mine in stackoverflow and out of which solution in #2 seems to be related to mine but I would like to know more about #4. Any leads are much appreciated. Thanks
     function MainCard(){
    
        const [data, setData] = useState({took: {}, timed_out: false, _shards: [], hits: 
            {total: {}, max_score: {}, hits: []}});
        const [pc, setPc] = useState("");    
    
        useEffect(() => {
            axios.get("http://localhost:9200/first_name/_search")
            .then(response => {
                    setData(response.data) 
                 
            });
        }, []);   
    
        return (
            <div>
                <Card className="customCard"> 
                <Card.Body>    
                    <select name="postcode" id="postcode">
                       {data.hits.hits.map(hit => {
                                              setPc(hit._id);
                                              return hit;
                                            })
                                      .map(hit => <option value={hit._id}>{hit._id}</option>)  
                      }                
                    </select>    
                    <select name="type-of-service" id="type-of-service">
                        {data.hits.hits.filter(hit => hit._id===pc)
                                        .map(hit => 
                                            <option value={hit._source}>{hit._source}</option>                                       
                                           )}                
                    </select>                                    
                   
                </Card.Body>
                </Card>                    
            </div>
        )
    
    } 
     
    
    export default MainCard;
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Hari Rao
  • 2,990
  • 3
  • 21
  • 34
  • 3
    `setPc(hit._id);` is being called in the render, which means its being called every render, causing another render, causing it to be called again, etc. What is the purpose of `setPc(hit._id);`? You should see that removing it stops the infinite loop. – Nick Sep 06 '21 at 22:05
  • @Nick thanks, yes if I remove it, it does not loop but I don't get the desired result either. The purpose is I want the user to select the post code and I want to set the selected set postcode setPc(hit._id);, then based on the post code I want to retrieve the source i.e hit._source. Any suggestion on where I can hold on to that post code that is selected? – Hari Rao Sep 06 '21 at 22:49

1 Answers1

1

You wrote very interesting code. The render layer and logic layer should be in this relationship.

Think -> Render

Which means your code should look like the following.

  const App = () => {
    // any logic i want to do
    // do it
    return (
      // here's my render based on states
      // try not to come up more logic here
    )
  }

You might ask how I can think again after the render. The think part has to be triggered by additional user actions. Otherwise you are writing a game which evolves with time, but React isn't a game machine, it's a UI library, the base case is to deal with a one time render upon user actions.

So how to fix your stuff.

  <select onChange={onChange} />

Ask yourself if a user select a different option, what should I do, look for an event handler which does that.

windmaomao
  • 7,120
  • 2
  • 32
  • 36