第一次写:
class FilterableProductTable1 extends React.Component{
constructor (props) {
super(props);
this.state = {
productCategoryRow: data7.title,
productName: data1.name,
productPrice: data1.price
}
}
render () {
return(
<div className="FilterProductTable">
<SearchBar/>
<ProductTable
productCategoryRow={this.state.productCategoryRow}
productName={this.state.productName} productPrice={this.state.productPrice}
/>
</div>
)
}
}
class SearchBar extends React.Component{
constructor (props) {super(props);}
render () {
return(
<div className="SearchBar">
<form>
<input type="text" placeholder="Search..."/>
<label className="label">
<input type="checkbox" value="false"/>Only show products is stock.
</label>
</form>
</div>
)
}
}
class ProductTable extends React.Component{
constructor (props) {super(props);}
render () {
return(
<div className="ProductTable">
<ProductCategoryRow productCategoryRow={this.props.productCategoryRow}/>
<ProductRow productName={this.props.productName} productPrice={this.props.productPrice}/>
</div>
)
}
}
class ProductCategoryRow extends React.Component{
constructor (props) {super(props);}
render () {
return(
<h2>{this.props.productCategoryRow}</h2>
)
}
}
class ProductRow extends React.Component{
constructor (props) {super(props);}
render () {
return(
<ul>
<li>
<span>{this.props.productName}</span>
<em>{this.props.productPrice}</em>
</li>
</ul>
)
}
}
class ProductData {
constructor (category, price, stocked, name) {
this.category = category;
this.price = price;
this.stocked = stocked;
this.name = name;
}
}
class TitleData {
constructor (title) {
this.title = title;
}
}
const data1 = new ProductData('Sporting Goods', '$49.99', 'true', 'Football');
const data2 = new ProductData('Sporting Goods', '$9.99', 'true', 'Baseball');
const data3 = new ProductData('Sporting Goods', '$29.99', 'false', 'Basketball');
const data4 = new ProductData('Electronics', '$99.99', 'true', 'iPod Touch');
const data5 = new ProductData('Electronics', '$399.99', 'false', 'iPhone 5');
const data6 = new ProductData('Electronics', '$199.99', 'true', 'Nexus 7');
const data7 = new TitleData('Sporting Goods');
const data8 = new TitleData('Electronics');
//React方式构建渲染UI
export default FilterableProductTable1;
总结:Lce易塔云建站-模板下载,web开发资源,技术博客遇到父子组件不很少,一般写法固定从子组件往上写,顺序方便一些。Lce易塔云建站-模板下载,web开发资源,技术博客
不是每一个class组件都要写constructor,如果数据是来源于自己,那就再写不迟。Lce易塔云建站-模板下载,web开发资源,技术博客
在render开始时,首先把需要用到的属性变量声明一下,养成良好习惯。
render () {
const item = this.props.item;
const price = this.props.price;
return(
因为开发环境是在react下,所以在任何return后面直接HTML语句都不应该报错,不要用旧习惯再写单引号了。Lce易塔云建站-模板下载,web开发资源,技术博客
数据处理,可以直接把数组或者对象直接当做JSX语法标签的一个属性带进去,不需要之前把数据排布好,没必要。Lce易塔云建站-模板下载,web开发资源,技术博客
哪里用到数组的值,再在那里用数组方法把数据取出来即可。其实并没有把方法抽离。全程是带着大数组进去渲染的。Lce易塔云建站-模板下载,web开发资源,技术博客Lce易塔云建站-模板下载,web开发资源,技术博客第二次写:
class ProductCategoryRow extends React.Component{
// Before constructor (props) {super(props);} //什么内部属性都没用,那就不用写
render () {
const category = this.props.category;
return(
<h2>{category}</h2>
)
}
}
class ProductRow extends React.Component{
render () {
const item = this.props.item;
const price = this.props.price;
return(
<li>
<span>{item}</span>
<em>{price}</em>
</li>
)
}
}
class SearchBar extends React.Component{
render () {
const filterText = this.props.filterText;
const inStockOnly = this.props.inStockOnly;
return(
<form>
<input type="text" placeholder="Search..." defaultValue={filterText}/>
<label className="label">
<input type="checkbox" defaultChecked={inStockOnly} />Only show products is stock.
</label>
</form>
)
}
}
class ProductTable extends React.Component{
render () {
const filterText = this.props.filterText;
const inStockOnly = this.props.inStockOnly;
const rows = [];
const productLists = this.props.products;
let lastCategory = null;
productLists.forEach(
(item,i) => {
if (item.name.indexOf(filterText) === -1) {
return;
}
if (inStockOnly && !item.stocked) {
return;
};
if(item.category !== lastCategory){
rows.push(
<ProductCategoryRow key={item.category} category={item.category}/>
)
};
rows.push(
<ProductRow item={item.name} price={item.price} key={i}/>
);
lastCategory = item.category;
}
)
return(
<div>
<ul>
{/*因为rows上面返回的是虚拟机DOM,所以可以直接在JSX里渲染了。*/}
{rows}
</ul>
</div>
)
}
}
class FilterableProductTable3 extends React.Component{
constructor (props) {
super(props);
this.state = {
filterText : 'ball',
inStockOnly : true
}
}
render () {
return(
<div>
<SearchBar filterText={this.state.filterText} inStockOnly={this.state.inStockOnly}/>
<table width="377" >
<tbody>
<tr>
<td align="middle" valign="middle">Names</td>
<td align="middle" valign="middle">Prices</td>
</tr>
</tbody>
</table>
<ProductTable products={PRODUCTS} filterText={this.state.filterText} inStockOnly={this.state.inStockOnly}/>
</div>
)
}
}
const PRODUCTS = [
{category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'},
{category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'},
{category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'},
{category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'},
{category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'},
{category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'}
];
确定state存放的为止。Lce易塔云建站-模板下载,web开发资源,技术博客
注意:React中的数据流是单向的,并随着组件层级从上往下传递。Lce易塔云建站-模板下载,web开发资源,技术博客
判断方法:Lce易塔云建站-模板下载,web开发资源,技术博客
1、找到根据这个state进行渲染的所有组件。Lce易塔云建站-模板下载,web开发资源,技术博客
2、找到他们的共同所有者(common owner)组件(差不多类似于父组件)Lce易塔云建站-模板下载,web开发资源,技术博客
3、该共同所有者组件或者比它层级更高的组件应该拥有state。Lce易塔云建站-模板下载,web开发资源,技术博客
4、如果是找不到合适的位置来存放state,就直接创建一个,并将该组件置于高于共同所有者组件层级的位置。Lce易塔云建站-模板下载,web开发资源,技术博客
我们考虑:Lce易塔云建站-模板下载,web开发资源,技术博客
1、ProductTable 需要根据state删选产品列表。SearchBar需要展示搜索词和复选框的状态。Lce易塔云建站-模板下载,web开发资源,技术博客
2、他们的共同所有者是FilterableProductTable。Lce易塔云建站-模板下载,web开发资源,技术博客
3、因此,搜索词和复选框的值应该很自然地存放在FilterableProductTable组建中。Lce易塔云建站-模板下载,web开发资源,技术博客
now,我们已经决定把这些state存放在FilterableProductTable中。Lce易塔云建站-模板下载,web开发资源,技术博客
首先,将实例属性 this.state={filterText='', inStockOnly: false}添加到constructor中。Lce易塔云建站-模板下载,web开发资源,技术博客
然后,将filterText和inStockOnly作为props传入ProductTable和SearchBar。Lce易塔云建站-模板下载,web开发资源,技术博客
最后,用这些props筛选ProductTable中的产品信息,并设置SearchBar的表单值。
class ProductCategoryRow extends React.Component{
// Before constructor (props) {super(props);} //什么内部属性都没用,那就不用写
render () {
const category = this.props.category;
return(
<h2>{category}</h2>
)
}
}
class ProductRow extends React.Component{
render () {
const item = this.props.item;
const price = this.props.price;
return(
<li>
<span>{item}</span>
<em>{price}</em>
</li>
)
}
}
class ProductTable extends React.Component{
render () {
const filterText = this.props.filterText;
const inStockOnly = this.props.inStockOnly;
const rows = [];
const productLists = this.props.products;
let lastCategory = null;
productLists.forEach(
(item,i) => {
if (item.name.indexOf(filterText) === -1) {
return;
}
if (inStockOnly && !item.stocked) {
return;
};
if(item.category !== lastCategory){
rows.push(
<ProductCategoryRow key={item.category} category={item.category}/>
)
};
rows.push(
<ProductRow item={item.name} price={item.price} key={i}/>
);
lastCategory = item.category;
}
)
return(
<div>
<ul>
{/*因为rows上面返回的是虚拟机DOM,所以可以直接在JSX里渲染了。*/}
{rows}
</ul>
</div>
)
}
}
class SearchBar extends React.Component{
constructor (props) {
super(props);
this.zhishiyonglaizhixingeryi = this.zhishiyonglaizhixingeryi.bind(this);
this.checkedChange = this.checkedChange.bind(this);
}
zhishiyonglaizhixingeryi(e) { //只是用来执行一条语句而已,叫什么名字无所谓,目的用于:给外部父组件的属性:onFilterTextChange,传入一个值
this.props.onFilterTextChange(e.target.value);
// console.log(this.props.onFilterTextChange); //打印出来是一个函数
}
checkedChange(e){
this.props.onInStockOnlyChnage(e.target.checked);
}
render () {
const filterText = this.props.filterText;
const inStockOnly = this.props.inStockOnly;
return(
<form>
<input type="text" placeholder="Search..." defaultValue={filterText} onChange={this.zhishiyonglaizhixingeryi}/>
<label className="label">
<input type="checkbox" defaultChecked={inStockOnly} onChange={this.checkedChange}/>Only show products is stock.
</label>
</form>
)
}
}
class FilterableProductTable4 extends React.Component{
constructor (props) {
super(props);
this.state = {
filterText : '',
inStockOnly : false
};
this.handleFilterTextChange = this.handleFilterTextChange.bind(this);
this.handleInStockOnlyChange = this.handleInStockOnlyChange.bind(this);
}
handleFilterTextChange(ahsasfasf){ //ahsasfasf 只是一个外参,叫什么名字都无所谓,是内部组件zhishiyonglaizhixingeryi方法执行的
return this.setState({filterText: ahsasfasf})
}
handleInStockOnlyChange(hahahaha){
this.setState({inStockOnly: hahahaha})
}
render () {
return(
<div>
<SearchBar
filterText={this.state.filterText}
inStockOnly={this.state.inStockOnly}
onFilterTextChange={this.handleFilterTextChange}
onInStockOnlyChnage={this.handleInStockOnlyChange}
/>
<table width="377" >
<tbody>
<tr>
<td align="middle" valign="middle">Names</td>
<td align="middle" valign="middle">Prices</td>
</tr>
</tbody>
</table>
<ProductTable products={PRODUCTS} filterText={this.state.filterText} inStockOnly={this.state.inStockOnly}/>
</div>
)
}
}
const PRODUCTS = [
{category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'},
{category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'},
{category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'},
{category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'},
{category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'},
{category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'}
];
//React方式构建渲染UI
export default FilterableProductTable4;
添加反向数据流。Lce易塔云建站-模板下载,web开发资源,技术博客
到目前为止,我们已经借助自上而下传递的props和state渲染了一个应用。现在我们将尝试Lce易塔云建站-模板下载,web开发资源,技术博客
让数据反向传递:处于较低层次的表单组件更新较高层级的FilterableProductTable中的state。Lce易塔云建站-模板下载,web开发资源,技术博客
Lce易塔云建站-模板下载,web开发资源,技术博客
React通过一种比传统的双向绑定略微繁琐的方法来实现反向数据传递。有助于理解程序的运作方式。Lce易塔云建站-模板下载,web开发资源,技术博客
Lce易塔云建站-模板下载,web开发资源,技术博客
如果你现在就搜索框输入值或勾选复选框,React不会产生任何反应。这是正常的,因为我们已经将Lce易塔云建站-模板下载,web开发资源,技术博客
input的值设置为了从FilterableProductTable传递而来的固定值。Lce易塔云建站-模板下载,web开发资源,技术博客
Lce易塔云建站-模板下载,web开发资源,技术博客
让我们来梳理一下需要实现的功能:Lce易塔云建站-模板下载,web开发资源,技术博客
1、每当用户改变表单值,我们需要改变state来反应用户的当前输入。Lce易塔云建站-模板下载,web开发资源,技术博客
2、由于state只能由拥有它们的组件进行更改,FilterableProductTable必须将一个能触发Lce易塔云建站-模板下载,web开发资源,技术博客
state改变的回调函数传递给SearchBar。Lce易塔云建站-模板下载,web开发资源,技术博客
3、我们可以使用输入框的onChange事件来监视用户输入的变化,并通知父组件FilterableProductTableLce易塔云建站-模板下载,web开发资源,技术博客
传递给SearchBar的那个函数(那是一个回调函数callback)。Lce易塔云建站-模板下载,web开发资源,技术博客
4、然后,该回调函数将更新stateLce易塔云建站-模板下载,web开发资源,技术博客Lce易塔云建站-模板下载,web开发资源,技术博客□,默认状态。Lce易塔云建站-模板下载,web开发资源,技术博客
Lce易塔云建站-模板下载,web开发资源,技术博客□,输入a。Lce易塔云建站-模板下载,web开发资源,技术博客
Lce易塔云建站-模板下载,web开发资源,技术博客
Lce易塔云建站-模板下载,web开发资源,技术博客
□,勾选复选框。Lce易塔云建站-模板下载,web开发资源,技术博客
Lce易塔云建站-模板下载,web开发资源,技术博客
