将道具传递给克隆的子元素,给出未知道具警告
Passing props to a cloned child element giving Unknown Prop warning
我在 React 中有一个 AdminLayout,它依次以这种方式加载子元素:
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 中的闪存状态。但是,使用代码 {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...了解我的内部组件是什么样子也可能有所帮助。我试图过滤掉任何不必要的东西......:[=14=]
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
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>
)
}
好的,问题的根源最终是我使用 react-router 不正确。在我添加问题的最后一部分之前,这是不可能看到的,它表明我正在从 sub-component LocationEdit
.
渲染 AdminLayout
我这样做是因为 react-router 我直接加载该页面,我没有意识到我实际上需要先加载布局,并且需要将子页面定义为子标签。下面是我原来的路线和我做的改动:
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>
标记上,而不是像我想象的那样加载到实际组件上。
我在 React 中有一个 AdminLayout,它依次以这种方式加载子元素:
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 中的闪存状态。但是,使用代码 {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...了解我的内部组件是什么样子也可能有所帮助。我试图过滤掉任何不必要的东西......:[=14=]
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
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>
)
}
好的,问题的根源最终是我使用 react-router 不正确。在我添加问题的最后一部分之前,这是不可能看到的,它表明我正在从 sub-component LocationEdit
.
AdminLayout
我这样做是因为 react-router 我直接加载该页面,我没有意识到我实际上需要先加载布局,并且需要将子页面定义为子标签。下面是我原来的路线和我做的改动:
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>
标记上,而不是像我想象的那样加载到实际组件上。