Реакция: не может получить доступ к пропущенным реквизитам (но МОЖЕТ получить доступ к реквизитам с маршрутизатора) - PullRequest
0 голосов
/ 25 сентября 2018

Дочерний компонент с именем Edit получает props.match из маршрута ('/: id / edit'), но я не могу получить доступ к другим реквизитам в <Edit />, отправленным из родительского компонента <Chirp />.

Разве нельзя отправить реквизит обоими способами?

Моя первоначальная проблема состояла в том, что я хотел получить доступ к реквизиту из <Edit />, не отображая все в Edit на странице Chirp.Поэтому я отправил реквизит по нажатию кнопки Edit.В противном случае <Edit /> прекрасно отображает все свои html.

console.log (this.props) показывает соответствие, местоположение и историю.Я пробовал this.props.match.params и this.props.user и т. Д., Но получаю только неопределенное значение.

Chirp.jsx (parent - также дочерний компонент)

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;

Ответы [ 3 ]

0 голосов
/ 26 сентября 2018

Первоначальная проблема заключается в том, что реквизиты не передаются компоненту <Edit /> в соединении маршрутизатора.Наиболее эффективное решение приходит с этого YouTube: Pass Props To React Router Link Component

Просто добавьте свойства к «to» в ссылке с помощью синтаксиса ниже.Передать реквизит в «состоянии».

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

Затем в компоненте Link (дочерний) получите доступ к реквизиту с помощью

this.props.location.state.user
this.props.location.state.text

Также будет работать другое решение, представленное на этой странице;Вместо определения маршрута для этой ссылки в app.jsx, определите его в родительском компоненте.Это потребует еще нескольких шагов:

import Route, Switch, & Edit переупорядочить структуру Route при рендеринге;т. е. обернуть return в <Router >, переместить домой Link и т. д. добавить эту встроенную функцию в маршрут: render={route => <Edit match={route.match} user={this.state.user} text={this.state.text}

Но проблема, возникающая в этом методе, заключается в том, что домашняя ссылка и щебетание 'user' и 'text'показать в компоненте редактирования.

0 голосов
/ 26 сентября 2018

Проблема с дочерним компонентом заключается в том, что вы определили метод конструктора внутри него, не передавая реквизиты в метод super и constructor для родительского компонента. Таким образом, вы никогда не получите реквизиты внутри дочернего компонента.

Есть два решения:

1) Удалить метод конструктора из дочернего компонента 2) Если вы не хотите удалять конструктор по какой-либо причине, просто передайте реквизиты в метод super и constructor в нем.

Пример:

class Edit extends Component {
    constructor(props) {
    super(props);
    this.state = {
        newUser: "",
        newText: ""
    }
 }

 render() {
    console.log(this.props)
 }
}

Надеюсь, это решит вашу проблему

0 голосов
/ 25 сентября 2018

Вы не можете render компонент onClick, как этот.
Плюс, editClick ничего не возвращает.

Я предлагаю хранить логическое значение в состоянии, таком как isEditMode и условный рендер компонент:

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

Вы можете использовать рендер .

Проблема здесь в том, что ваши данные для этого компонента не находятся в корневом компоненте, но это нормально, поскольку вы можете визуализировать <Route /> на любом уровне в дереве компонентов.

Вы можетесм. работающий пример в этом фрагменте

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...