将传递的道具反应到自定义轮播中
React passing props into custom carousel
我正在使用 this.props 然后选择数组来填充我的属性等。有没有更好的方法可以传递道具以缩短 this.props?还有其他人看到这有什么问题吗?还是自动滑动,不是"controlled".
import React, { Component } from 'react';
import { Carousel as BSCarousel } from 'react-bootstrap';
class Carousel extends Component {
getInitialState() {
return {
index: 0,
direction: null,
};
}
handleSelect(selectedIndex, e) {
this.setState({
index: selectedIndex,
direction: e.direction,
});
}
render() {
return (
<BSCarousel activeIndex={this.state.index} direction={this.state.direction} onSelect={this.handleSelect}>
<BSCarousel.Item>
<img alt={this.props.alt} src={this.props.image} />
<BSCarousel.Caption>
<h3>{this.props.heading}</h3>
<p>{this.props.caption}</p>
</BSCarousel.Caption>
</BSCarousel.Item>
</BSCarousel>
);
}
}
export default Carousel;
编辑
import React, { Component } from 'react';
import { Carousel as BSCarousel } from 'react-bootstrap';
class Carousel extends Component {
constructor(props) {
super(props);
this.state = { index: 0, direction: null };
this.handleSelect = this.handleSelect.bind(this);
}
render() {
const { alt, image, heading, caption } = this.props;
return (
<BSCarousel activeIndex={this.state.index} direction={this.state.direction} onSelect={this.handleSelect}>
<BSCarousel.Item>
<img alt={alt} src={image} />
<BSCarousel.Caption>
<h3>{heading}</h3>
<p>{caption}</p>
</BSCarousel.Caption>
</BSCarousel.Item>
</BSCarousel>
);
}
}
export default Carousel;
Is there a better way where I can pass props to shorten from this.props?
使用解构
render() {
const {alt, image, heading, caption} = this.props
return (
<BSCarousel activeIndex={this.state.index} direction={this.state.direction} onSelect={this.handleSelect}>
<BSCarousel.Item>
<img alt={alt} src={image} />
<BSCarousel.Caption>
<h3>{heading}</h3>
<p>{caption}</p>
</BSCarousel.Caption>
</BSCarousel.Item>
</BSCarousel>
);
}
Also does anyone else see anything wrong with this?
您需要先绑定 handleSelect
,然后再将其作为回调传递
class Carousel extends Component {
constructor(props) {
super(props)
this.state = {/* initial state goes here*/}
this.handleSelect = this.handleSelect.bind(this)
}
... rest of your code
你正在混合es5 and es6
写一个React组件,es6
中没有getInitialState
方法。使用 constructor
初始化 state
值。
像这样:
class Carousel extends Component {
constructor() {
super();
this.state = {
index: 0,
direction: null,
};
}
....
您可以在 render
方法中使用 Object destructuring 而不是访问 this.props.key
,然后通过键名直接访问值,如下所示:
render(){
const {alt, image, heading, caption} = this.props;
console.log(alt, image, heading, caption);
return (
<BSCarousel activeIndex={this.state.index} direction={this.state.direction} onSelect={this.handleSelect}>
<BSCarousel.Item>
<img alt={alt} src={image} />
<BSCarousel.Caption>
<h3>{heading}</h3>
<p>{caption}</p>
</BSCarousel.Caption>
</BSCarousel.Item>
</BSCarousel>
)
}
检查这个片段它会抛出错误,state is not defined:
class App extends React.Component{
getInitialState(){
return {a:1}
}
render(){
return <div>Hello: {this.state.a}</div>
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<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='app'/>
如果你厌倦了到处看到 this.props,你可以 destructure 这样的道具(与 this.state 相同,或任何其他对象你想分开):
render() {
const { alt, heading, image, caption } = this.props;
return (
<BSCarousel activeIndex={this.state.index} direction={this.state.direction} onSelect={this.handleSelect}>
<BSCarousel.Item>
<img alt={alt} src={image} />
<BSCarousel.Caption>
<h3>{heading}</h3>
<p>{caption}</p>
</BSCarousel.Caption>
</BSCarousel.Item>
</BSCarousel>
);
}
因为您使用的是 ES6 类,所以您必须进行不同的设置。
将您的 getInitialState()
函数替换为:
constructor(props) {
super(props);
this.state = {
index: 0,
direction: null,
};
this.handleSelect = this.handleSelect.bind(this);
}
你问过是否有办法清理对 this.props
的所有调用,所以这里的大部分答案都提到了解构,这是清理对 [=14= 的调用的好方法],但随后您还询问是否有人认为您的实现有任何问题,并且一些答案指出使用 getInitialState
的过时用法(而不是简单地在构造函数中设置您的初始组件级状态并分配给this.state = {}
), 但其他答案没有抓住的事实是您的实施将您的 "Carousel" 限制为仅通过道具 传入的单个项目。 您应该做的是允许自己灵活地通过 props 将任意数量的项目传递给 Carousel 组件。
对我来说,如果它只允许通过 props 传入单个项目,那将是一个高度限制的 Carousel 组件。
这就是我要做的。此实现:
- 使用解构来清理所有重复的点符号,
- 在构造函数中声明组件级状态,
- 允许您通过道具传递任意数量的轮播项目,
- 声明一个渲染
Carousel.Item
元素集合的 renderItems() 函数
- 调用
CarouselItem
组件,该组件负责创建实际的 Carousel.Item
- 确保在构造函数中将任何自定义函数绑定到
this
(当您的函数需要引用 this
上下文时需要),
- 使用扩展运算符真正清理对
this
的多次调用
components/Carousel.js
import React, { Component } from 'react';
import { Carousel } from 'react-bootstrap';
import CarouselItem from './CarouselItem'; // 5
class CustomCarousel extends Component {
constructor(props) {
super(props);
this.state = { // 2
index: 0,
direction: null,
};
this.handleSelect = this.handleSelect.bind(this); // 6
}
handleSelect(selectedIndex, e) {
this.setState({
index: selectedIndex,
direction: e.direction,
});
}
generateItems() { // 4
const { items } = this.props;
return items.map((item, index) => {
const active = (index === item.id);
return (<CarouselItem
key={`CI${item.id}`}
active={active}
direction={this.state.direction}
{...item} // 7
/>);
});
}
render() {
return (
<Carousel
activeIndex={this.state.index}
direction={this.state.direction}
onSelect={this.handleSelect}
>
{this.generateItems()}
</Carousel>
);
}
}
export default CustomCarousel;
components/Carousel/CarouselItem.js
import React from 'react';
import { Carousel } from 'react-bootstrap';
const CarouselItem = (props) => {
const { id, active, direction, image, alt, heading, caption } = props; // 1
return (
<Carousel.Item
index={id}
active={active}
direction={direction}
>
<img alt={alt} src={image} />
<Carousel.Caption>
<h3>{heading}</h3>
<p>{caption}</p>
</Carousel.Caption>
</Carousel.Item>
);
};
export default CarouselItem;
现在你有一个干净的 Carousel 组件,可以接受任意数量的潜在 "Items"。
您可以这样调用您的自定义轮播:
import CustomCarousel from './path/to/Carousel';
const arrayOfItemObjects = [
{...},
{...},
{...}
];
<CustomCarousel
items={arrayOfItemObjects} // 3
/>
我正在使用 this.props 然后选择数组来填充我的属性等。有没有更好的方法可以传递道具以缩短 this.props?还有其他人看到这有什么问题吗?还是自动滑动,不是"controlled".
import React, { Component } from 'react';
import { Carousel as BSCarousel } from 'react-bootstrap';
class Carousel extends Component {
getInitialState() {
return {
index: 0,
direction: null,
};
}
handleSelect(selectedIndex, e) {
this.setState({
index: selectedIndex,
direction: e.direction,
});
}
render() {
return (
<BSCarousel activeIndex={this.state.index} direction={this.state.direction} onSelect={this.handleSelect}>
<BSCarousel.Item>
<img alt={this.props.alt} src={this.props.image} />
<BSCarousel.Caption>
<h3>{this.props.heading}</h3>
<p>{this.props.caption}</p>
</BSCarousel.Caption>
</BSCarousel.Item>
</BSCarousel>
);
}
}
export default Carousel;
编辑
import React, { Component } from 'react';
import { Carousel as BSCarousel } from 'react-bootstrap';
class Carousel extends Component {
constructor(props) {
super(props);
this.state = { index: 0, direction: null };
this.handleSelect = this.handleSelect.bind(this);
}
render() {
const { alt, image, heading, caption } = this.props;
return (
<BSCarousel activeIndex={this.state.index} direction={this.state.direction} onSelect={this.handleSelect}>
<BSCarousel.Item>
<img alt={alt} src={image} />
<BSCarousel.Caption>
<h3>{heading}</h3>
<p>{caption}</p>
</BSCarousel.Caption>
</BSCarousel.Item>
</BSCarousel>
);
}
}
export default Carousel;
Is there a better way where I can pass props to shorten from this.props?
使用解构
render() {
const {alt, image, heading, caption} = this.props
return (
<BSCarousel activeIndex={this.state.index} direction={this.state.direction} onSelect={this.handleSelect}>
<BSCarousel.Item>
<img alt={alt} src={image} />
<BSCarousel.Caption>
<h3>{heading}</h3>
<p>{caption}</p>
</BSCarousel.Caption>
</BSCarousel.Item>
</BSCarousel>
);
}
Also does anyone else see anything wrong with this?
您需要先绑定 handleSelect
,然后再将其作为回调传递
class Carousel extends Component {
constructor(props) {
super(props)
this.state = {/* initial state goes here*/}
this.handleSelect = this.handleSelect.bind(this)
}
... rest of your code
你正在混合es5 and es6
写一个React组件,es6
中没有getInitialState
方法。使用 constructor
初始化 state
值。
像这样:
class Carousel extends Component {
constructor() {
super();
this.state = {
index: 0,
direction: null,
};
}
....
您可以在 render
方法中使用 Object destructuring 而不是访问 this.props.key
,然后通过键名直接访问值,如下所示:
render(){
const {alt, image, heading, caption} = this.props;
console.log(alt, image, heading, caption);
return (
<BSCarousel activeIndex={this.state.index} direction={this.state.direction} onSelect={this.handleSelect}>
<BSCarousel.Item>
<img alt={alt} src={image} />
<BSCarousel.Caption>
<h3>{heading}</h3>
<p>{caption}</p>
</BSCarousel.Caption>
</BSCarousel.Item>
</BSCarousel>
)
}
检查这个片段它会抛出错误,state is not defined:
class App extends React.Component{
getInitialState(){
return {a:1}
}
render(){
return <div>Hello: {this.state.a}</div>
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<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='app'/>
如果你厌倦了到处看到 this.props,你可以 destructure 这样的道具(与 this.state 相同,或任何其他对象你想分开):
render() {
const { alt, heading, image, caption } = this.props;
return (
<BSCarousel activeIndex={this.state.index} direction={this.state.direction} onSelect={this.handleSelect}>
<BSCarousel.Item>
<img alt={alt} src={image} />
<BSCarousel.Caption>
<h3>{heading}</h3>
<p>{caption}</p>
</BSCarousel.Caption>
</BSCarousel.Item>
</BSCarousel>
);
}
因为您使用的是 ES6 类,所以您必须进行不同的设置。
将您的 getInitialState()
函数替换为:
constructor(props) {
super(props);
this.state = {
index: 0,
direction: null,
};
this.handleSelect = this.handleSelect.bind(this);
}
你问过是否有办法清理对 this.props
的所有调用,所以这里的大部分答案都提到了解构,这是清理对 [=14= 的调用的好方法],但随后您还询问是否有人认为您的实现有任何问题,并且一些答案指出使用 getInitialState
的过时用法(而不是简单地在构造函数中设置您的初始组件级状态并分配给this.state = {}
), 但其他答案没有抓住的事实是您的实施将您的 "Carousel" 限制为仅通过道具 传入的单个项目。 您应该做的是允许自己灵活地通过 props 将任意数量的项目传递给 Carousel 组件。
对我来说,如果它只允许通过 props 传入单个项目,那将是一个高度限制的 Carousel 组件。
这就是我要做的。此实现:
- 使用解构来清理所有重复的点符号,
- 在构造函数中声明组件级状态,
- 允许您通过道具传递任意数量的轮播项目,
- 声明一个渲染
Carousel.Item
元素集合的 renderItems() 函数 - 调用
CarouselItem
组件,该组件负责创建实际的Carousel.Item
- 确保在构造函数中将任何自定义函数绑定到
this
(当您的函数需要引用this
上下文时需要), - 使用扩展运算符真正清理对
this
的多次调用
components/Carousel.js
import React, { Component } from 'react';
import { Carousel } from 'react-bootstrap';
import CarouselItem from './CarouselItem'; // 5
class CustomCarousel extends Component {
constructor(props) {
super(props);
this.state = { // 2
index: 0,
direction: null,
};
this.handleSelect = this.handleSelect.bind(this); // 6
}
handleSelect(selectedIndex, e) {
this.setState({
index: selectedIndex,
direction: e.direction,
});
}
generateItems() { // 4
const { items } = this.props;
return items.map((item, index) => {
const active = (index === item.id);
return (<CarouselItem
key={`CI${item.id}`}
active={active}
direction={this.state.direction}
{...item} // 7
/>);
});
}
render() {
return (
<Carousel
activeIndex={this.state.index}
direction={this.state.direction}
onSelect={this.handleSelect}
>
{this.generateItems()}
</Carousel>
);
}
}
export default CustomCarousel;
components/Carousel/CarouselItem.js
import React from 'react';
import { Carousel } from 'react-bootstrap';
const CarouselItem = (props) => {
const { id, active, direction, image, alt, heading, caption } = props; // 1
return (
<Carousel.Item
index={id}
active={active}
direction={direction}
>
<img alt={alt} src={image} />
<Carousel.Caption>
<h3>{heading}</h3>
<p>{caption}</p>
</Carousel.Caption>
</Carousel.Item>
);
};
export default CarouselItem;
现在你有一个干净的 Carousel 组件,可以接受任意数量的潜在 "Items"。
您可以这样调用您的自定义轮播:
import CustomCarousel from './path/to/Carousel';
const arrayOfItemObjects = [
{...},
{...},
{...}
];
<CustomCarousel
items={arrayOfItemObjects} // 3
/>