一个名为Edit的子组件正在从路由('/:id / edit')接收props.match,但我无法访问由父组件<Edit />
发送的<Chirp />
中的其他props。>
两种方法都无法发送道具吗?
最初的问题是我想从<Edit />
访问道具,而无需在“调频”页面的“编辑”中渲染所有内容。因此,我在“编辑”的按钮点击上发送了道具。 <Edit />
会使其所有html正常显示。
console.log(this.props)显示匹配,位置和历史记录。我已经尝试过this.props.match.params和this.props.user等,但只能得到未定义。
Chirp.jsx(父级-也是子级组件)
import React, { Component, Fragment } from 'react';
import { BrowserRouter as Router, Link } from 'react-router-dom';
import 'isomorphic-fetch';
import Edit from './edit';
class Chirp extends Component {
constructor() {
super();
this.state = {
user: "",
text: ""
}
this.editClick = this.editClick.bind(this);
}
componentDidMount() {
fetch(`http://127.0.0.1:3000/api/chirps/${this.props.match.params.id}`)
.then(response => response.json())
.then(data => {
this.setState({
user: data.user,
text: data.text
})
})
.catch(err => console.log(err))
}
editClick() {
<Edit user={this.state.user} text={this.state.text} />
console.log("props passed")
}
render() {
return (
<div>
<Fragment>
<Link to="/" className="homelink" style={{ textDecoration: "none" }}>Home</Link>
</Fragment>
<div className="current">
<div className="flex-column">
<div className='chirps'>
<p>{this.state.user}: {this.state.text}</p>
<Fragment >
<Link to={`/${this.props.match.params.id}/edit`}><button onClick={this.editClick}>Edit</button></Link>
</Fragment>
<Fragment >
<Link to={`/${this.props.match.params.id}/delete`}><button className="delete">x</button></Link>
</Fragment>
</div>
</div>
</div>
</div>
)
}
}
export default Chirp;
edit.jsx(子组件)
import React, { Component, Fragment } from 'react';
import { BrowserRouter as Router, Link } from 'react-router-dom';
import 'isomorphic-fetch';
class Edit extends Component {
constructor() {
super();
this.state = {
newUser: "",
newText: ""
}
}
render() {
console.log(this.props)
return (
<div>
<Fragment>
<Link to="/" className="homelink" style={{ textDecoration: "none" }}>Home</Link>
</Fragment>
<h2>Edit Your Chirp</h2>
<div className="input">
<form action="">
<input
type="text"
placeholder={this.props.user}
size="10"
id="user"
name="user"
// onChange={this.inputHandler}
// defaultValue={this.props.user}
/>
<input
type="text"
placeholder={this.props.text}
size="60"
id="text"
name="text"
// onChange={this.inputHandler}
// defaultValue={this.state.text}
/>
<button
onClick={this.editChirps}
id="submit">
Submit
</button>
</form>
</div>
</div>
)
}
}
export default Edit;
app.jsx
import React, { Component, Fragment } from 'react';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import Home from './home'
import Chirp from './chirp'
import Edit from './edit'
import Delete from './delete'
class Navigation extends Component {
render() {
return (
<Router>
<Fragment>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/:id/edit" component={Edit} />
<Route path="/:id/delete" component={Delete} />
<Route path="/:id" component={Chirp} />
</Switch>
</Fragment>
</Router>
)
}
}
export default Navigation;
答案 0 :(得分:3)
您不能render
这样的组件onClick
。
另外,editClick
不返回任何内容。
我的建议是在状态为isEditMode
和conditional render的组件中存储一个布尔值:
editClick(){
this.setState(state => ({isEditMode: !state.isEditMode}));
}
和渲染中:
{this.state.isEditMode && <Edit user={this.state.user} text={this.state.text} />}
这是一个运行中的小例子:
const Edit = ({ someProp }) => <input placeholder={someProp} />;
class App extends React.Component {
state = { isEditMode: false };
toggleEdit = () =>
this.setState(state => ({ isEditMode: !state.isEditMode }));
render() {
const { isEditMode } = this.state;
return (
<div>
<button onClick={this.toggleEdit}>Toggle Edit</button>
{isEditMode && <Edit someProp="Edit me" />}
</div>
);
}
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);
<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>
<div id="root"/>
修改
更新之后,我现在看到的问题是您为Route
渲染<Edit />
的方式。
您没有传递任何道具:
<Route path="/:id/edit" component={Edit} />
您可以使用render prop。
这里的问题是该组件的数据不在根组件上,但是可以在组件树下的任何级别渲染<Route />
。
您可以在this snippet
中看到正在运行的示例答案 1 :(得分:0)
最初的问题是道具没有传递到路由器Link中的<Edit />
组件。最有效的解决方案来自以下YouTube:Pass Props To React Router Link Component
使用以下语法在“链接”中简单地添加属性。以“状态”传递道具。
<Link to={{
pathname: `/${this.props.match.params.id}/edit`,
state: {
user: this.state.user,
text: this.state.text
}
}}>
<button onClick={this.editClick}>Edit</button>
</Link>
然后在“链接(子)”组件上,使用来访问道具
this.props.location.state.user
this.props.location.state.text
此页面上提供的另一种解决方案也可以使用;无需在app.jsx中定义此Link的路由,而是在父组件中定义它。这将需要更多步骤:
导入路线,切换和编辑
在渲染中重新排列Route结构;即在<Router >
中将return换行,将主链接移回原位,等等
将此内联函数添加到路由:render={route => <Edit match={route.match} user={this.state.user} text={this.state.text}
但是此方法带来的一个问题是主页链接以及线性调频调“用户”和“文本”显示在“编辑”组件中。
答案 2 :(得分:0)
子组件的问题是您在其中定义了构造方法,而没有将道具传递给父组件的super和构造方法。这样您将永远不会在子组件内部获得道具。
有两种解决方法。
1)从子组件中删除构造函数方法 2)如果由于某种原因不想删除构造函数,则只需将props传递给其中的super和constructor方法。
示例:
class Edit extends Component {
constructor(props) {
super(props);
this.state = {
newUser: "",
newText: ""
}
}
render() {
console.log(this.props)
}
}
希望这可以解决您的问题