向导和向导页
我正在尝试构建一个通用的Wizard和WizardPages,以便在我的应用程序中可以重复使用。我认为向导组件负责管理状态,而WizardPage将作为包装器工作,并将呈现Back,Cancel和Next按钮。它假设Next按钮(也许Back也是)应该发送一个redux动作。此操作可能会有所不同,具体取决于要包装的组件。这就是我的(不完整版):
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import withWizardLayout from '../../hoc/WithWizardLayout';
class Wizard extends Component {
constructor(props) {
super(props);
this.state = {
page: 0,
};
}
nextPage = () => {
this.setState({ page: this.state.page + 1 });
};
previousPage = () => {
this.setState({ page: this.state.page - 1 });
};
render() {
const { wizardPages } = this.props;
const { page } = this.state;
const wizardItem = wizardPages[page];
const nextPage = this.nextPage;
const previousPage = this.previousPage;
const ComponentWrapped = withWizardLayout(wizardItem.ComponentWrapped, nextPage, previousPage);
return (
<ComponentWrapped />
);
}
}
export default Wizard;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { compose } from 'react-apollo';
import { connect } from 'react-redux';
import { Flex, Box } from 'reflexbox';
import { BlueRoundButton, GreyRoundButton } from '../components/Button';
export default function withWizardLayout(ComponentDependent, nextPageCallBack, previousPageCallback) {
class WizardPage extends Component {
previousPage = () => {
};
nextPage = () => {
this.props.test();
};
render() {
const { ComponentWrapped, isFirstPage, isLastPage } = ComponentDependent;
return (
<Flex column>
<ComponentWrapped
isLastPage={isLastPage}
isFirstPage={isFirstPage}
>
<Flex justify='flex-end'>
<Flex mr='auto' w={0.1}>
<GreyRoundButton style={{ fontWeight: '500', position: 'relative', top: '10%' }}>Back</GreyRoundButton>
</Flex>
<Flex w={0.08} mr={2} align='center' justify='center' style={{ textAlign: 'center' }}>
<span>Cancel</span>
</Flex>
<Flex w={0.15} justify='center'>
<BlueRoundButton onClick={this.nextPage} style={{ position: 'relative', top: '10%', fontWeight: '500' }}>Continue</BlueRoundButton>
</Flex>
</Flex>
</ComponentWrapped>
</Flex>
);
}
}
CustomersContainer
import { compose } from 'react-apollo';
import { connect } from 'react-redux';
import CustomerImport from '../components/Settings/CustomerImport';
import { withWizardLayout } from '../hoc/WithWizardLayout';
const mapStateToProps = null;
const mapDispatchToProps = dispatch => (
{
test: () => (dispatch(console.log("hi"))),
}
);
export default compose(connect(null, mapDispatchToProps))(CustomerImport);
已连接的组件
import React, { Component } from 'react';
import styled from 'styled-components';
import {
SettingBlock,
NotifyBlock,
SuccessMessage,
ErrorMessage,
Instructions,
} from './styles';
import ExcelUploader from '../ExcelUploader';
const ProgressBar = styled.div`
width: 0;
height: 30px;
background-color: Green;
`;
const ExcelWrapper = styled.div`
margin-bottom: 4rem;
`;
export default class CustomerImport extends Component {
constructor(props) {
super(props);
this.state = {
progress: 0,
notify: {
success: {
message: '',
active: false,
},
error: {
message: '',
active: false,
},
},
};
}
render() {
const { success, error } = this.state.notify;
const ButtonsWrapper = this.props.children;
return (
<div>
<NotifyBlock>
<SuccessMessage className={success.active ? 'active' : null}>{success.message}</SuccessMessage>
<ErrorMessage className={error.active ? 'active' : null}>{error.message}</ErrorMessage>
</NotifyBlock>
<SettingBlock>
<h3>
Import your customers
</h3>
<ProgressBar style={{ width: `${this.state.progress}%` }} />
<Instructions>
Select an Excel file containing your customer information.
Need a template? <a href="">Grab one here.</a>
</Instructions>
<ExcelWrapper>
<ExcelUploader />
</ExcelWrapper>
{ButtonsWrapper}
</SettingBlock>
</div>
);
}
}
这就是我应该如何呈现通用向导,我们可以拥有X向导页面:
const wizardPages = [
{
ComponentWrapped: CustomersContainer,
isFirstPage: false,
isLastPage: false,
},
];
<Wizard wizardPages={wizardPages} />
这种方法的问题在于我想在withWizardLayout中使用按钮的onClick:
1)对父亲执行回调(可能,我作为道具处理者传递)
2)调用收到的容器调度操作。 (我无法访问已发送的操作,在本例中为this.props.test)
我如何重构这一点,想一个通用的方法来处理这个问题?我认为另一种重构方法(具有不同的withWizardLayout函数,但我在控制台上有渲染问题)。 也许我没有以最好的方式设计这个。 救命啊!