简体   繁体   English

故事书旋钮未更新

[英]Storybook Knobs not updating

I have setup storybook for my react project, and i have 2 stories. 我为我的React项目设置了故事书,并且我有2个故事。 One that is a simple button and a larger component. 一个简单的按钮和一个较大的组件。 I use knobs for both, it works fine of the simple button but it dose not update the larger component (The withInfo addon actaully shows the correct updated information from knobs, but the component dose not update.) This tells me there is something wrong with my component and not storybook knobs. 我对两者都使用了旋钮,它在简单的按钮上都可以正常工作,但是它不会更新较大的组件(withInfo插件实际上从旋钮显示了正确的更新信息,但是组件未更新。)这告诉我这有问题我的组件,而不是故事书旋钮。 But the component seems to work just fine in my application. 但是该组件似乎在我的应用程序中正常工作。

My Button story 我的按钮故事

  .add('with text', () => {
    const buttonText = text('Button Text', 'Hello Button');
    return (
      <Button onClick={action('clicked')}>{buttonText}</Button>)
  })

My larger component story 我较大的故事

import React from 'react';
import { storiesOf } from '@storybook/react';
import { text, number, file, boolean } from '@storybook/addon-knobs/react';

import blueSignImage from '../src/images/sign-3.jpg';
import SignType from '../src/components/SignType/index';

storiesOf('Sign Type', module)
    .add('With current signs and requested signs', () => {
        const typeId = text("Type id", "test-1234");
        const availableSigns = number('Avalible Signs', 5);
        const requestedSigns = number('Requested Signs', 3);
        const typeName = text("Type name", "Blue Sign Image");
        const isSaving = boolean("Is saving", false);
        const onRequsetSigns = (id, value) => {
            console.log("Got requset for " + value + " signs for id " + id);
        };

        return (
            <SignType typeId={typeId} 
                availableSigns={availableSigns} 
                requestedSigns={requestedSigns} 
                typeName={typeName} 
                image={blueSignImage} 
                isSaving={isSaving}
                onRequsetSigns={onRequsetSigns}
                />
        )
    });

The component 组件

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Card, CardContent, CardMedia, Typography, Button, Slider, LinearProgress } from '@material-ui/core';
import SendIcon from '@material-ui/icons/Send';
import CloseIcon from '@material-ui/icons/Close';
import "./index.scss";

class SignType extends PureComponent {

    constructor(props) {        
        super(props);
        this.state = {
            typeId: props.typeId,
            typeName: props.typeName,
            image: props.image,
            availableSigns: props.availableSigns,
            requestedSigns: props.requestedSigns,
            isSaving: props.isSaving,
            onRequsetSigns: props.onRequsetSigns,

            // Local Vars
            requestAmount: 5,
            showOrderMore: false,
        };

        this.onOrderMoreClicked = this.onOrderMoreClicked.bind(this);
        this.onHideOrderMore = this.onHideOrderMore.bind(this);
        this.onRequestAmountChanged = this.onRequestAmountChanged.bind(this);
        this.onSaveRequest = this.onSaveRequest.bind(this);
    }

    componentDidMount() {

    }

    onOrderMoreClicked() {
        this.setState({ showOrderMore: true });
    }
    onHideOrderMore() {
        this.setState({ showOrderMore: false });
    }
    onRequestAmountChanged(event, value) {
        this.setState({ requestAmount: value });
    }
    onSaveRequest() {
        this.setState({ showOrderMore: false });
        this.state.onRequsetSigns(this.state.typeId, this.state.requestAmount);
    }

    render() {
        const { typeId, availableSigns, requestedSigns, image, typeName, showOrderMore, isSaving, requestAmount } = this.state;
        return (
            <Card className="signType">
                <CardMedia
                    className="cover"
                    image={image}
                    title="Live from space album cover"
                />
                <div className="details">
                    <CardContent className="content">
                        <Typography component="h5" variant="h5">
                            {typeName}
                        </Typography>
                        <Typography variant="body1" color="textPrimary">
                            {availableSigns} signs available
                            {!showOrderMore && !isSaving && (
                            <Button color="primary" onClick={this.onOrderMoreClicked}>
                                Order more
                            </Button>)}
                        </Typography>

                        {requestedSigns > 0 && (
                            <Typography variant="subtitle2" color="textSecondary">
                                {requestedSigns} requested signs pending
                        </Typography>
                        )}
                    </CardContent>
                    {showOrderMore && (
                        <div className="requestSignsControl">
                            <Typography id={"request-slider-" + typeId} variant="h6" color="textPrimary">
                                Request additional signs
                                </Typography>
                            <Slider
                                defaultValue={5}
                                aria-labelledby={"request-slider-" + typeId}
                                valueLabelDisplay="auto"
                                step={1}
                                marks
                                min={1}
                                max={25}
                                onChangeCommitted={this.onRequestAmountChanged}
                            />
                            <div>
                                <Button variant="contained" color="secondary" onClick={this.onHideOrderMore} className="icon">
                                    <CloseIcon className="icon" />
                                </Button>
                                <Button variant="contained" color="primary" onClick={this.onSaveRequest} className="icon">
                                    Send Request
                                    <SendIcon className="icon" />
                                </Button>
                            </div>
                        </div>
                    )}
                    {isSaving && <LinearProgress />}
                </div>
            </Card>
        );
    }
}

SignType.propTypes = {
    typeId: PropTypes.string.isRequired,
    typeName: PropTypes.string.isRequired,
    image: PropTypes.string.isRequired,
    availableSigns: PropTypes.number.isRequired,
    requestedSigns: PropTypes.number.isRequired,
    isSaving: PropTypes.bool.isRequired,
    onRequsetSigns: PropTypes.func.isRequired,
};

export default SignType;

My storybook config 我的故事书配置

import { configure, addDecorator } from '@storybook/react';
import { withKnobs } from '@storybook/addon-knobs';
import { withInfo } from '@storybook/addon-info';
import { withConsole } from '@storybook/addon-console';

import 'typeface-roboto';

// automatically import all files ending in *.stories.js
const req = require.context('../stories', true, /\.stories\.js$/);
function loadStories() {
  req.keys().forEach(filename => req(filename));
}

addDecorator(withInfo);
addDecorator(withKnobs);
addDecorator((storyFn, context) => withConsole()(storyFn)(context));

configure(loadStories, module);

my addons.js 我的addons.js

import '@storybook/addon-actions/register';
import '@storybook/addon-knobs/register';
import '@storybook/addon-links/register';
import '@storybook/addon-actions/register';

Your component is only using props when you get the initial state, you aren't even using them during the render. 您的组件仅在获得初始状态时才使用道具,甚至在渲染过程中也没有使用道具。

Sort of an anti-pattern - https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html 某种反模式-https: //reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html

Also not exactly what I would call a 'pure' component - https://reactjs.org/docs/react-api.html#reactpurecomponent 同样也不是我所谓的“纯”组件-https://reactjs.org/docs/react-api.html#reactpurecomponent

Unless you actually update your state (which you do in your handlers), you won't see an update based on those props. 除非您实际更新状态(在处理程序中执行),否则您将不会看到基于这些道具的更新。

That said if you wish to continue down this path you'll need a way to react to those prop changes. 也就是说,如果您希望继续沿着这条道路前进,则需要一种对那些道具更改做出反应的方法。 You could make use of the componentWillReceiveProps lifecycle and call setState here. 您可以利用componentWillReceiveProps生命周期并在此处调用setState。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM