我正在学习使用JSX和ES6的React,我对如何使用ReactRouter4创建组件和路由到不同视图有了相当不错的处理。
我仍然无法弄清楚的是,例如我如何创建一个管理页面,我在其中输入我的投资组合的工作细节,并将所有工作渲染在另一个页面上,可能是投资组合页面。
这就是我所拥有的。
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()
的唯一方法,React方法componentWillMount()
和componentWillUnmount()
来处理状态,默认{{1} }。关于这个组件还有一点需要注意的是,它正在调用一个名为render()
的组件,该组件通过Firebase将所有详细信息提供给在线数据库。因此,如果这与它所处的位置相关,那么请考虑到这一点,否则不要冒汗。
../base
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;
这是包含我正在使用ReactRouter
的地方的文件:
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
1}} component,它创建对象,然后将该对象抛出到Portfolio.js
组件,以便它可以通过Work.js
组件呈现它,并且它不会将对象添加到DB。
当我将所有组件放在同一页面上时这是有效的,这是不理想的,因为访问我的投资组合的任何人都可以添加作品。当然,我可以开始学习身份验证的过程以及如何根据用户凭据使该组件显示或消失,但我更愿意学习能够将我的管理页面放在一个单独的视图中的非常有价值的技能,因为我看到另一个学习这样做的应用程序。
很想听到别人对此的看法以及他们可能在哪里确定我在这里失败。
顺便说一句,我知道我有其他组件,例如Nav.js
和Title.js
,但为了说明这个例子,它们不是必需的。
谢谢。
答案 0 :(得分:0)
您可以将组件作为道具传递,使用React Router时可以使用named components。
对于兄弟姐妹之间的数据共享,最好建议将数据放在父组件上,尽管您可以使用上下文,但是这个is not advised可能在将来的版本中无法使用。
如果你需要在另一个组件上创建一些东西(不知道为什么),你可以传递一个可以渲染它的函数。