我有一个AdminLayout in react,它反过来以这种方式加载子元素:
class AdminLayout extends Component {
constructor(props){
super(props)
this.state = {
flash: { msg: "some message", type: undefined}
}
}
updateFlash(flash){
this.state.flash = flash
}
render() {
return(
<div>
<FlashMessage flash={this.state.flash} />
<NavBar/>
{ React.cloneElement(this.props.children, {updateFlash: this.updateFlash})}
</div>
)
}
}
这里的想法是我打算让我的子元素更新AdminLayout中的flash状态。但是,使用代码{updateFlash: this.updateFlash}
,我收到以下错误:
Warning: Unknown prop `updateFlash` on <div> tag. Remove this prop from the element. For details, see https://facebook.github.io/react/warnings/unknown-prop.html
in div (created by Grid)
in Grid (created by LocationEdit)
我查看了文档,我不相信我在做任何案例。我也没有尝试直接在任何div上设置道具。
有没有人见过这样的东西?
Hrm ......也许有助于了解我的内部组件是什么样的。我试图挑出任何不必要的......:
import React, {Component} from 'react'
import AdminLayout from '../components/layouts/AdminLayout'
import LocationsSource from '../sources/LocationsSource'
import {Button, Grid, Row, Col, FormGroup, FormControl, ControlLabel, HelpBlock} from 'react-bootstrap'
import { browserHistory } from 'react-router'
class LocationEdit extends Component {
constructor(props) {
super(props)
this.handleSubmit = this.handleSubmit.bind(this)
this.state = {
loading: true,
location: {
name: "",
site_link: "",
description: ""
}
}
}
handleSubmit = (event) => {
event.preventDefault()
let data = this.state.location
if(data._id != undefined) {
LocationsSource.update(data).then((response) => {
browserHistory.push('/admin/locations/');
})
} else {
LocationsSource.create(data).then((response) => {
browserHistory.push('/admin/locations/');
})
}
}
componentDidMount() {
if(this.props.params.id)
LocationsSource.find(this.props.params.id).then((result) => {
this.setState({loading: false, location: result})
})
else{
this.setState({loading: false, location: {}})
}
}
handleChange = (event) => {
let change = {location: this.state.location}
change['location'][event.target.name] = event.target.value
this.setState(change)
}
componentWillUnmount() {}
render() {
let location = this.state.location
if(this.state.loading)
return(
<AdminLayout>
<Row>
<img src="/assets/images/loading.gif" />
</Row>
</AdminLayout>
)
else
return(
<AdminLayout>
<Grid>
<Row>
<Col xs={8} md={8}>
<h2>Location</h2>
</Col>
</Row>
<Row>
<Col xs={8} md={8}>
<form onSubmit={this.handleSubmit}>
<FormGroup controlId={"name"}>
<ControlLabel>Name:</ControlLabel>
<FormControl onChange={this.handleChange} name="name" type="text" defaultValue={location.name} />
</FormGroup>
<Button type="submit">
Submit
</Button>
</form>
</Col>
</Row>
</Grid>
</AdminLayout>
)
}
}
export default LocationEdit
答案 0 :(得分:0)
updateFlash(flash){
this.setState({ flash });
}
render() {
return(
<div>
<FlashMessage flash={this.state.flash} />
<NavBar/>
{ React.cloneElement(this.props.children, {updateFlash: this.updateFlash.bind(this)})}
</div>
)
}
答案 1 :(得分:0)
好的,问题的根源是我正在使用react-router错误。直到我添加问题的最后一部分,它才显示我正在从子组件AdminLayout
呈现LocationEdit
,这是不可能看到的。
我这样做是因为我正在反应路由器直接加载该页面,我没有意识到我实际上需要首先加载布局,并且需要将子页面定义为子标签。接下来是我的原始路线和我所做的改变:
render((
<Router history={browserHistory}>
<Route path="/admin/" component={Locations} />
<Route path="locations" component={LocationEdit} />
</Router>
), document.getElementById('app'));
的变化:
render((
<Router history={browserHistory}>
<Route path="/admin/" component={AdminLayout} >
<Route path="locations" component={LocationEdit} />
</Route>
</Router>
), document.getElementById('app'));
然后我从我的LocationEdit页面中取出了AdminLayout
标签。我觉得它试图将props
直接加载到<Grid>
标记上,而不是按照我的想法加载到实际组件上。