即使正在传递道具,组件也不返回UI

时间:2017-07-25 09:04:48

标签: javascript reactjs

我对React很新,所以我认为这里的问题可能非常基础。我正在显示一个区域列表,当用户点击某个区域时,我通过props将对象传递给CountryList组件:

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

SelectRegion组件工作正常,但CountryList仅渲染没有内容的组件。这是CountryList组件。

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

如果我查看检查器,我可以看到当用户点击状态更新的区域时,CountryList组件被添加到页面(以及<ul></ul>)并且它具有适当的道具(一个对象)。我错过了什么让组件不显示?

如果它有用,这是整个组件:

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>

1 个答案:

答案 0 :(得分:2)

<ul></ul>必须表示props.countryCodes未设置,Object.entries的循环对我来说很好。问题似乎是回调'updateBoth',onSelect={this.updateBoth}没有将参数传递给updateBoth(updateRegion, updateCountries),因此您的州无法为countryCodes设置任何值。

修改

我可以使用您的代码:

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