The component does not return an interface even if the props are supplied

I'm new to React, so I think the problem here is likely to be pretty simple. I am showing a list of regions, and when the user clicks on a region, I pass the object via props to the CountryList component:

render() {
        return (
            <div>
                <SelectRegion 
                    selectedRegion={this.state.selectedRegion} 
                    onSelect={this.updateBoth} />
                { !this.state.countryCodes
                    ? "Select a region"
                    : <CountryList countryCodes={this.state.countryCodes} /> }
            </div>
        )
    }

      

The SelectRegion component works fine, but CountryList only provides a component with no content. Here is the CountryList component.

function CountryList(props) {
    return (
        <ul className="country-list">
            {Object.entries(props.countryCodes).forEach(([key, val]) => {
                return (
                    <li 
                        key={key}
                        className="country-item" >
                            <div className="country-code">{key}</div>
                            <ul className="space-list-items">
                                <li>
                                    <img
                                        className="flag"
                                        src={`http://www.geognos.com/api/en/countries/flag/${key}.png`}
                                        alt={"Flag for " + val}
                                    />
                                </li>
                            </ul>
                    </li>
                )
            })}
        </ul>
    )
}

      

If I look in the inspector, I can see that when the user clicks on the area, the state is updated, the CountryList component is added to the page (as well <ul></ul>

) and that it has the appropriate props (object). What am I missing to render the component?

If useful, this is the whole component:

function App () {
	return (
	  <div>
	  	<Selector />
	  </div>  
	)
}

function SelectRegion (props) {
	const regionCountry = {
		"Europe": {
			"PL": "Poland",
			"HU": "Hungary",
			"DE": "Germany",
			"AT": "Austria",
			"DK": "Denmark", 
			"ES": "Spain", 
			"GR": "Greece",
			"IT": "Italy",
			"CH": "Switzerland",
			"RU": "Russia",
			"FR": "France",
			"BE": "Belgium",
			"LU": "Luxembourg",
			"SE": "Sweden",
			"NO": "Norway",
			"SI": "Slovenia",
			"LT": "Lithuania",
			"CY": "Cyprus",
			"LV": "Latvia",
			"BG": "Bulgaria",
			"HR": "Croatia",
			"GB": "United Kingdom",
			"IE": "Ireland",
			"GE": "Georgia",
			"RO": "Romania",
			"FI": "Finland",
			"NL": "Netherlands",
			"ME": "Montenegro"

		},
		"Americas": {
			"CA": "Canada",
			"US": "USA",
			"MX": "Mexico",
			"BR": "Brazil",
			"CL": "Chile",
			"AR": "Argentina",
			"CO": "Columbia",
			"UY": "Uruguay"
		},
		"APAC": {
			"AU": "Australia",
			"NZ": "New Zealand",
			"KZ": "Kazakhstan",
			"JP": "Japan",
			"TH": "Thailand",
			"TW": "Taiwan"
		},
		"Middle East & Africa": {
			"IL": "Israel",
			"TR": "Turkey",
			"AE": "UAE",
			"SA": "South Africa"
		}
	}

	return (
		<ul className="regions">
			{Object.keys(regionCountry).map((region) => {
				return(
					<li
					style={region === props.selectedRegion ? {color: '#d0021b'} : null}
					onClick={props.onSelect.bind(null, region, regionCountry[region])}
	            	key={region} >
	            		{region}
            		</li>
            	)
			})}
        </ul>
	)
}

function CountryList(props) {
	return (
		<ul className="country-list">
			{Object.entries(props.countryCodes).forEach(([key, val]) => {
				return (
					<li 
						key={key}
						className="country-item" >
							<div className="country-code">{key}</div>
							<ul className="space-list-items">
								<li>
									<img
										className="flag"
										src={"http://www.geognos.com/api/en/countries/flag/"+key+".png"}
										alt={"Flag for " + val}
									/>
								</li>
							</ul>
					</li>
				)
			})}
		</ul>
	)
}

class Selector extends React.Component {
	constructor(props) {
		super(props);

		this.state = {
			selectedRegion: null,
			countryCodes: null
		}

		this.updateRegion = this.updateRegion.bind(this);
		this.updateCountries = this.updateCountries.bind(this);
		this.updateBoth = this.updateBoth.bind(this);
	}

	updateRegion(region) { selectedRegion: region }

	updateCountries(countries) { countryCodes: countries }

	updateBoth(updateRegion, updateCountries) {
		this.setState(() => {
			return {
				selectedRegion: updateRegion,
				countryCodes: updateCountries
			}
		})
	}

	render() {
		return (
			<div>
				<SelectRegion 
					selectedRegion={this.state.selectedRegion} 
					onSelect={this.updateBoth} />
				{ !this.state.countryCodes
					? "Select a region"
					: <CountryList countryCodes={this.state.countryCodes} /> }
			</div>
		)
	}
}

ReactDOM.render(
	<App />,
	document.getElementById('app')
)
      

body {
  font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
}

a {
  text-decoration: none;
  color: #d0021b;
}

ul {
  padding: 0;
}

li {
  list-style-type: none;
}

.button {
  color: #e6e6e6;
  background: #0a0a0a;
  border: none;
  font-size: 16px;
  border-radius: 3px;
  width: 200px;
  text-align: center;
  display: block;
  padding: 7px 0;
  margin: 10px auto;
}

.button:hover:enabled {
  background: linear-gradient(#1a1a1a,#0a0a0a);
  color: #fff;
  text-decoration: none;
}

.button:active {
  transform: translateY(1px);
}

.regions {
  display: flex;
  justify-content: center;
}

.regions li {
  font-size: 1.5em;
  margin: 10px;
  font-weight: bold;
  cursor: pointer;
}

.country-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}

.country-item {
  margin: 20px;
  text-align: center;
}

.country-code {
  margin: 20px;
  text-align: center;
}
      

<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>

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Hello Express</title>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
      

Run codeHide result


+3


source to share


1 answer


Empty <ul></ul>

should mean props.countryCodes

not set, the loop for Object.entries looks good to me. The problem is that your "updateBoth" callback is to blame for onSelect={this.updateBoth}

not passing any parameters to updateBoth(updateRegion, updateCountries)

, so your state cannot set any value for countryCodes.

Edit



I can get your code to work with:

function CountryList(props) {
    console.log(props);
    return (
        <ul className="country-list">
            {
                Object.keys(props.countryCodes).map((key) => {
                    console.log(key);
                    return (
                        <li
                            key={ key }
                            className="country-item" >
                            <div className="country-code">{key}</div>
                            <ul className="space-list-items">
                                <li>
                                    <img
                                        className="flag"
                                        src={"http://www.geognos.com/api/en/countries/flag/"+key+".png"}
                                        alt={"Flag for " + props.countryCodes[key]}
                                    />
                                </li>
                            </ul>
                        </li>
                    );
                })

            }
        </ul>
    )
}

      

+2


source







All Articles