Я изучаю React с использованием JSX и ES6, и у меня есть довольно приличная ручка о том, как создавать компоненты и направлять их на разные виды с помощью ReactRouter4.Как вводить данные в один компонент React и визуализировать его в другом?
Что я до сих пор не смог выяснить, например, как создать страницу администратора, где я введу детали работы для своего портфолио и выполнить все работы на другой странице, предположительно на странице Портфолио ,
Вот что у меня есть.
App.js
загружает Portfolio.js
компонент
import React from 'react';
import Navigation from './Navigation';
import Title from './Title';
import Portfolio from './Portfolio';
class App extends React.Component {
render() {
return(
<div className="container-fluid">
<div className="container">
<div className="row">
<div className="col-sm-12">
<Navigation />
<Title title="kuality.io"/>
<section className="app">
<Portfolio works={this.props.works} />
</section>
</div>
</div>
</div>
</div>
)
}
}
export default App;
Portfolio.js
компонент имеет конструктор, чтобы связать уникальный метод с именем addWork()
, РЕАКТ методы componentWillMount()
и componentWillUnmount()
для обработки состояния, и по умолчанию render()
. Еще одна вещь, которая стоит упомянуть об этом компоненте, заключается в том, что он вызывает компонент под названием ../base
, который имеет все подробности в онлайн-БД через Firebase. Поэтому, если это имеет значение, где это место, тогда учтите это, иначе не потейте.
import React from 'react';
import Work from './Work';
import Admin from './Admin';
import base from '../base';
class Portfolio extends React.Component {
constructor() {
super();
this.addWork = this.addWork.bind(this);
// getInitialState
this.state = {
works: {}
};
}
componentWillMount() {
this.ref = base.syncState(`/works`
, {
context: this,
state: 'works'
})
}
componentWillUnmount() {
base.removeBinding(this.ref);
}
addWork(work) {
// update our state
const works = {...this.state.works};
// add in our new works with a timestamp in seconds since Jan 1st 1970
const timestamp = Date.now();
works[`work-${timestamp}`] = work;
// set state
this.setState({ works });
}
render() {
return(
<div>
<section className="portfolio">
<h3>Portfolio</h3>
<ul className="list-of-work">
{
Object
.keys(this.state.works)
.map(key => <Work key={key} details={this.state.works[key]}/>)
}
</ul>
</section>
</div>
)
}
}
export default Portfolio;
Внутри Object
я картографирование через Work
компонента, который является только элементом списка, я сделал еще один компонент для и не очень актуален в этом вопросе.
И наконец, у меня есть компоненты Admin.js
и AddWorkForm.js
. Я отвлек AddWorkForm.js
, чтобы использовать его в другом месте, если это необходимо, в основном основная идея React Components, поэтому я решил сделать это именно так.
import React from 'react';
import Title from './Title';
import AddWorkForm from './AddWorkForm';
class Admin extends React.Component {
constructor() {
super();
this.addWork = this.addWork.bind(this);
// getInitialState
this.state = {
works: {}
};
}
addWork(work) {
// update our state
const works = {...this.state.works};
// add in our new works with a timestamp in seconds since Jan 1st 1970
const timestamp = Date.now();
works[`work-${timestamp}`] = work;
// set state
this.setState({ works });
}
render() {
return(
<div className="container-fluid">
<div className="container">
<div className="row">
<div className="col-sm-12">
<Title title="Admin"/>
<section className="admin">
<AddWorkForm addWork={this.addWork} />
</section>
</div>
</div>
</div>
</div>
)
}
}
export default Admin;
и AddWorkForm.js
компонент, который является в основном формой, которая onSubmit
создает объект и восстанавливает виде
import React from 'react';
class AddWorkForm extends React.Component {
createWork(event) {
event.preventDefault();
console.log('Creating some work');
const work = {
name: this.name.value,
desc: this.desc.value,
image: this.image.value
}
this.props.addWork(work);
this.workForm.reset();
}
render() {
return(
<form ref={(input) => this.workForm = input} className="work-edit form-group" onSubmit={(e) => this.createWork(e)}>
<input ref={(input) => this.name = input} type="text" className="form-control" placeholder="Work Title"/>
<textarea ref={(input) => this.desc = input} type="text" className="form-control" placeholder="Work Description"></textarea>
<input ref={(input) => this.image = input} type="text" className="form-control" placeholder="Work Image"/>
<button type="submit" className="btn btn-primary">+Add Work</button>
</form>
)
}
}
export default AddWorkForm;
Вот файл, который включает в себя, где я использую :
import React from 'react';
import { render } from 'react-dom';
// To render one method from a package user curly brackets, you would have to know what method you wan though
import { BrowserRouter, Match, Miss} from 'react-router';
import './css/normalize.css';
import './css/bootstrap.css';
import './css/style.css';
// import '../js/bootstrap.js';
import App from './components/App';
import WorkItem from './components/WorkItem';
import Capability from './components/Capability';
import Connect from './components/Connect';
import NotFound from './components/NotFound';
import Admin from './components/Admin';
const Root =()=> {
return(
<BrowserRouter>
<div>
<Match exactly pattern="/" component={App} />
<Match pattern="/work/:workId" component={WorkItem} />
<Match exactly pattern="/capability" component={Capability} />
<Match exactly pattern="/connect" component={Connect} />
<Match exactly pattern="/admin" component={Admin} />
<Miss component={NotFound} />
</div>
</BrowserRouter>
)
}
render (<Root />, document.querySelector('#main'));
Итак, вот что я пробовал и не смог выполнить, и это, скорее всего, какое-то решение this.props
, которого я не был способный определить, мне нужно создать work
в компоненте Admin.js
, который создает объект, а затем запустил этот объект для компонента Portfolio.js
, чтобы он мог визуализировать его через компонент Work.js
и он не добавляет объект в базу данных.
Это работает, когда я помещаю все компоненты на одну страницу, что не идеально, потому что тогда любой доступ к моему портфолио может добавить работу. Конечно, я мог бы начать процесс обучения аутентификации и как заставить этот компонент появляться или исчезать на основе учетных данных пользователя, но я бы скорее изучил очень ценный навык, чтобы иметь возможность иметь мою страницу администратора на отдельном представлении вместе, Я вижу еще одно приложение для изучения этого.
Хотелось бы услышать мнение других об этом и где они могут определить, что я здесь не сработал.
Btw, я понимаю, что у меня есть другие компоненты, такие как Nav.js
и Title.js
, но они не нужны, чтобы проиллюстрировать пример.
спасибо.
TLDR. Вы не можете обмениваться данными между двумя компонентами, которые находятся на одном уровне или в разных ветвях. Вам нужен либо родительский компонент, который хранит их, либо что-то вроде Redux. – zurfyx
Эхо, что говорит @zurfyx. Сохранение состояния в родительском компоненте Admin и Portfolio, вероятно, является хорошим первым подходом. Из любопытства, вы на самом деле используете какой-либо маршрутизатор? Можете ли вы показать код, в котором находятся ваши компоненты Match? – azium
@zurfyx Хорошо, я посмотрю на это. – MARS