简体   繁体   中英

Why my react component is not rendering?

This is my react functional component , I am sending inputs as props which are to be displayed and then looping through the inputs to check which inputs are to be displayed according to condition. This is my component :-

const TopInputComponent = (props) => {
   const inputs = props.inputs;
   inputs.map((input,index)=>{
        if(input.type == "textInput"){
             return (<Textfield  key={index}
                    onKeyDown={(event)=>{
                        if(event.key == "Enter"){
                            onFilterSelected({'min_price':parseInt(event.target.value)});
                        }
                    }}
                    label={input.placeholder}
                    floatingLabel
                /> )
         }else if(input.type == "selectInput"){
              return  (<div key={index}>
                        <label>{input.placeholder}</label>
                        <select >
                            <option value="1">1</option>
                            <option value="2">3</option>
                            <option value="4">4</option>
                            <option value="5">5</option>
                        </select>
                    </div>)
         }

    })  

}

I am getting this Error :

"A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object."

There are two, three, possibly four problems:

  1. You aren't returning anything out of the function, because you haven't returned the result of map .

  2. A React component must return a single element or null , it can't return an array.

  3. Within your map callback, you're only returning something if input.type is "textInput" or "selectInput" , not if it's something else. That will leave undefined values in your resulting array. If those are the only two possible values, change else if(input.type == "selectInput"){ to just } else { . If not, handle the other cases.

  4. floatingLabel in the Textfield 's start tag seems odd, it will be a freestanding boolean attribute.

So you'll probably want to wrap those elements in something, perhaps a div (see *** lines):

const TopInputComponent = (props) => {
   const inputs = props.inputs;
   return <div>{inputs.map((input,index)=>{     // ***
        if(input.type == "textInput"){
             return (<Textfield  key={index}
                    onKeyDown={(event)=>{
                        if(event.key == "Enter"){
                            onFilterSelected({'min_price':parseInt(event.target.value)});
                        }
                    }}
                    label={input.placeholder}
                    floatingLabel
                /> )
         } else { // *** Removed: if(input.type == "selectInput"){
              return  (<div key={index}>
                        <label>{input.placeholder}</label>
                        <select >
                            <option value="1">1</option>
                            <option value="2">3</option>
                            <option value="4">4</option>
                            <option value="5">5</option>
                        </select>
                    </div>)
         }
    })}</div>;                                  // ***
}

Simplified live example:

 const MyComponent = props => { const {inputs} = props; return <div> {inputs.map((input, index) => <input key={index} type={input.type} name={input.name} value={input.value || ''} />)} </div>; }; ReactDOM.render( <MyComponent inputs={[ {type: "text", name: "one"}, {type: "button", name: "btn", value: "Click me"} ]} />, document.getElementById("react") ); 
 <div id="react"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 

Inside map you are returning the elements, that elements will group into an array by map (returns an array ), You need to return the result of map also. You are returning an array but react component can't return an array, so wrap the map result inside a div .

Use this:

const TopInputComponent = (props) => {
   const inputs = props.inputs;
   return <div> { inputs.map((input,index)=>{   //added return
   ....

One more issue is, inside map if you don't return anything by default it will return undefined , you are using two condition, may be possible if none of them is true , in that case undefined will be returned. So always use a default case also, use it in this way:

return a.map(el => {
    if(/*condition 1*/)
        return //1;
    else if(/*condition 2*/)
        return //2;
    else
        return //3;
})

Check this example:

 a = [1,2,3,4,5,6]; function withoutReturn () { a.map(i => i); }; function withReturn () { return a.map(i => i); }; console.log('withoutReturn', withoutReturn()); console.log('withReturn', withReturn()) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM