代码之家  ›  专栏  ›  技术社区  ›  Sterling Butters

反应:更新组件属性

  •  1
  • Sterling Butters  · 技术社区  · 6 年前

    好吧,我已经正式花了好几个小时来解决这个问题,但我相信这是一个简单的解决办法。我是一个全新的反应和尝试创建一个自定义组件的PlotlyDash。

    问题

    我正在尝试更新的令牌属性 LoginForm 为任何熟悉的人使用格子链接的组件。你会注意到 handleOnSuccess 功能在 LoginForm.react.js 我可以检索令牌并将其显示在控制台中。我只想更新 token 性质 登录通知 在控制台中显示该值。

    下面是整个 loginform.react.js版本 :

    import React, { Component } from 'react';
    import Script from 'react-load-script';
    import PropTypes from 'prop-types';
    
    
    class LoginForm extends Component {
        constructor(props) {
            super(props);
    
            this.state = {
                linkLoaded: false,
                initializeURL: 'https://cdn.plaid.com/link/v2/stable/link-initialize.js',
            };
    
            this.onScriptError = this.onScriptError.bind(this);
            this.onScriptLoaded = this.onScriptLoaded.bind(this);
    
            this.handleLinkOnLoad = this.handleLinkOnLoad.bind(this);
    
            this.handleOnExit = this.handleOnExit.bind(this);
            this.handleOnEvent = this.handleOnEvent.bind(this);
            this.handleOnSuccess = this.handleOnSuccess.bind(this);
    
            this.renderWindow = this.renderWindow.bind(this);
        }
    
        onScriptError() {
            console.error('There was an issue loading the link-initialize.js script');
        }
    
        onScriptLoaded() {
            window.linkHandler = window.Plaid.create({
                apiVersion: this.props.apiVersion,
                clientName: this.props.clientName,
                env: this.props.env,
                key: this.props.publicKey,
                onExit: this.handleOnExit,
                onLoad: this.handleLinkOnLoad,
                onEvent: this.handleOnEvent,
                onSuccess: this.handleOnSuccess,
                product: this.props.product,
                selectAccount: this.props.selectAccount,
                token: this.props.token,
                webhook: this.props.webhook,
            });
    
            console.log("Script loaded");
        }
    
        handleLinkOnLoad() {
            console.log("loaded");
            this.setState({ linkLoaded: true });
        }
        handleOnSuccess(token, metadata) {
            console.log(token);
            console.log(metadata);
        }
        handleOnExit(error, metadata) {
            console.log('link: user exited');
            console.log(error, metadata);
        }
        handleOnLoad() {
            console.log('link: loaded');
        }
        handleOnEvent(eventname, metadata) {
            console.log('link: user event', eventname, metadata);
        }
    
        renderWindow() {
            const institution = this.props.institution || null;
            if (window.linkHandler) {
                window.linkHandler.open(institution);
            }
        }
    
        static exit(configurationObject) {
            if (window.linkHandler) {
                window.linkHandler.exit(configurationObject);
            }
        }
    
        render() {
            return (
                <div id={this.props.id}>
                    {this.renderWindow()}
                    <Script
                        url={this.state.initializeURL}
                        onError={this.onScriptError}
                        onLoad={this.onScriptLoaded}
                    />
                </div>
            );
        }
    }
    
    LoginForm.defaultProps = {
        apiVersion: 'v2',
        env: 'sandbox',
        institution: null,
        selectAccount: false,
        style: {
            padding: '6px 4px',
            outline: 'none',
            background: '#FFFFFF',
            border: '2px solid #F1F1F1',
            borderRadius: '4px',
        },
    };
    
    LoginForm.propTypes = {
        // id
        id: PropTypes.string,
    
        // ApiVersion flag to use new version of Plaid API
        apiVersion: PropTypes.string,
    
        // Displayed once a user has successfully linked their account
        clientName: PropTypes.string.isRequired,
    
        // The Plaid API environment on which to create user accounts.
        // For development and testing, use tartan. For production, use production
        env: PropTypes.oneOf(['tartan', 'sandbox', 'development', 'production']).isRequired,
    
        // Open link to a specific institution, for a more custom solution
        institution: PropTypes.string,
    
        // The public_key associated with your account; available from
        // the Plaid dashboard (https://dashboard.plaid.com)
        publicKey: PropTypes.string.isRequired,
    
        // The Plaid products you wish to use, an array containing some of connect,
        // auth, identity, income, transactions, assets
        product: PropTypes.arrayOf(
            PropTypes.oneOf([
                // legacy product names
                'connect',
                'info',
                // normal product names
                'auth',
                'identity',
                'income',
                'transactions',
                'assets',
            ])
        ).isRequired,
    
        // Specify an existing user's public token to launch Link in update mode.
        // This will cause Link to open directly to the authentication step for
        // that user's institution.
        token: PropTypes.string,
    
        // Set to true to launch Link with the 'Select Account' pane enabled.
        // Allows users to select an individual account once they've authenticated
        selectAccount: PropTypes.bool,
    
        // Specify a webhook to associate with a user.
        webhook: PropTypes.string,
    
        // A function that is called when a user has successfully onboarded their
        // account. The function should expect two arguments, the public_key and a
        // metadata object
        onSuccess: PropTypes.func,
    
        // A function that is called when a user has specifically exited Link flow
        onExit: PropTypes.func,
    
        // A function that is called when the Link module has finished loading.
        // Calls to plaidLinkHandler.open() prior to the onLoad callback will be
        // delayed until the module is fully loaded.
        onLoad: PropTypes.func,
    
        // A function that is called during a user's flow in Link.
        // See
        onEvent: PropTypes.func,
    
        // Button Styles as an Object
        style: PropTypes.object,
    
        // Button Class names as a String
        className: PropTypes.string,
    };
    
    export default LoginForm;
    

    这里是 App.js :

    // /* eslint no-magic-numbers: 0 */
    import React, { Component } from 'react';
    import { LoginForm } from '../lib';
    
    class App extends Component {
        constructor(props) {
            super(props);
            this.state = {
                token: null
            }
        }
    
        render() {
            return (
                <LoginForm
                    id="Test"
                    clientName="Plaid Client"
                    env="sandbox"
                    product={['auth', 'transactions']}
                    publicKey="7a3daf1db208b7d1fe65850572eeb1"
                    className="some-class-name"
                    apiVersion="v2"
                    token={this.state.token}
                >
                </LoginForm>
            );
        }
    }
    
    export default App;
    

    我认为有必要防止将任何功能分配给 登录通知 token={this.someFunction} 不可接受

    我还知道,直接更改属性的值(如果可能)是不可取的,即在逻辑上插入 this.props.token=token 进入 手法成功 函数可能工作(逻辑上-我知道它不工作),但这仍然不能真正提供在父进程和子进程之间更新组件的良好流程。

    我很感激所有的帮助,因为这是这个小项目的最后一步,我真的想不出来。事先谢谢!

    如果这样做更容易-您可以在此处克隆回购: https://github.com/SterlingButters/plaidash

    2 回复  |  直到 6 年前
        1
  •  0
  •   Yuan Ruo    6 年前

    updateToken App this.setState

    LoginForm handleOnSuccess

    App.react.js

    // pass this function as prop to LoginForm.
    // don't forget to bind to 'this'.
    updateToken(token, metadata) {
        ...
        this.setState({ token })
    }
    
    ...
    
    // in render function
    <LoginForm updateToken={updateToken} ... />
    

    LoginForm.react.js

    handleOnSuccess(token, metadata) {
        this.props.updateToken(token, metadata)
    }
    

    props

        2
  •  1
  •   helloitsjoe    6 年前

    handleUpdateToken

    class App extends Component {
      ...
      handleUpdateToken(token) {
        this.setState({ token });
      }
    
      ...
      render() {
        return (
          <LoginForm
            onUpdateToken={this.handleUpdateToken}
            ...other LoginForm props
          />
      }
    }
    

    handleOnSuccess(token, metadata) {
      console.log(token);
      console.log(metadata);
      this.props.onUpdateToken(token);
    }