react服务和组件之间如何通信?

Posted

技术标签:

【中文标题】react服务和组件之间如何通信?【英文标题】:How to communicate between react service and a component? 【发布时间】:2019-11-17 04:10:59 【问题描述】:

我创建了一个调用rest api的util .js文件,我需要在这个util(不是组件)和其他组件之间进行通信。

例如,在登录时,如果它未能引发登录组件将捕获并采取相应措施的事件。

不确定这是否是正确的方法(我是新手),怎么做?

【问题讨论】:

可以将回调函数传递给util函数。 【参考方案1】:

我实现了一个通量解决方案(尽管 redux 方法可能就足够了,一个商店 - 这是其余的服务 - 可以完成工作)

调度员:

 import  Dispatcher  from 'flux';

export default new Dispatcher();

RestService(存储):

import React, Component from 'react';
import ReactDOM from 'react-dom';
import App from '../App';

import EventEmitter from 'events';
import dispatcher from '../Dispatcher';
import * as Actions from "../actions/Actions";

const baseUrl = 'http:/.../WebServices/api';

class ApiService extends EventEmitter 

    constructor() 
        super();

        this.updateStatus = this.updateStatus.bind(this);

        this.state = 
            loginFailed: false
        
    

    getLoginStatus() 
        return this.state.loginFailed;
    

    updateStatus(status) 
        //this.setState(loginFailed: true);
        this.state.loginFailed = status;
    

    // module.exports = 

        /*export function*/ login(userName, password) 
            fetch(baseUrl + '/SessionManager/login?userName='
                + userName + '&password=' + password,
                
                    //method: 'GET',
                    //credentials: "same-origin",
                    //mode: "no-cors",
                    //headers: headers
                    //'Content-Type': 'application/json'
                
            ).then(
                (response) => 
                    localStorage.setItem('Response', JSON.stringify(response))
                    //console.log("Headers ======>", JSON.stringify(response.headers));

                    // Inspect the headers in the response
                    response.headers.forEach(console.log);
                    // OR you can do this
                    for (let entry of response.headers.entries()) 
                        console.log(entry);
                    

                    // let sid = getSessionCookie(); //document.cookie.match('sid=([^;]*)');
                    // console.log("Session Id: ", sid);
                    // localStorage.setItem('session', sid)

                    // let headers = response.headers.get('Set-Cookie')
                    // console.log("Headers: ", headers);
                    // localStorage.setItem('headers', headers)

                    if (response.status < 200 || response.status > 300) 
                        // console.log('Looks like there was a problem. Status Code: ' + response.status);
                        // this.state.showError = true;
                        // this.state.errorMessage = 'Please enter a valid credentials.';

                        //this.setState(loginFailed: true);
                        this.updateStatus(true);
                        this.emit("statusChanged", response);

                        return;
                     else 
                        //window.location.href = '/main';
                        ReactDOM.render(<App user=userName/>,
                            document.getElementById('root'));
                    

                    // Examine the text in the response
                    // response.json().then(function(data) 
                    //     console.log(data);
                    // );
                
            ).catch((error) => 
                console.error(error);
            );
        

        /*export function*/ getProjectDetails() 
            //let params = this.getSession();
            //console.log('Params....', params);


            fetch(baseUrl + '/ProjectManager/getProjectDetails',
                
                    //   //credentials: "include",
                    //   //credentials: "same-origin",
                    //   //crossdomain: true,
                    //   //mode: 'no-cors',
                    //headers: headers
                
            )
                .then(res => res.json())
                .then((data) => 
                    this.setState(projectsDetails: data)
                    console.log(data);
                )
                .catch(console.log);
        
    // 

    handleActions(action) 
        switch(action.type) 
            case "LOGIN": 
                this.login(action.user, action.password);
                //this.emit("change");
            
            // case "LOGIN_FAILURE": 
            //     this.setState(loginFailed: true);
            //     this.emit("change");
            // 
        
    


// const service = new ApiService();
// // Register dispatcher
// dispatcher.register(service.handleActions.bind(service));
// // Expose dispatcher globally
// window.dispatcher = dispatcher;

export default ApiService;

行动:

import dispatcher from '../Dispatcher';

export function login(user, password) 

    dispatcher.dispatch(
        type: "LOGIN",
        user: user,
        password: password
    )


登录组件:

import React,  Component  from 'react';
import Button, Form, TextInput from 'carbon-components-react';
import './Login.css';
//import * as service from  '../services/RestService.js';
import ApiService from '../stores/RestService.js';
import ReactDOM from "react-dom";
import App from "../App";
import * as Actions from "../actions/Actions";
import dispatcher from "../Dispatcher";


const apiService = new ApiService();

// Register dispatcher
dispatcher.register(apiService.handleActions.bind(apiService));
// Expose dispatcher globally
window.dispatcher = dispatcher;


class Login extends Component 

    //errorMessage;
    service;
    getLoginStatus;

    constructor(props) 
        super(props);
        this.getLoginStatus = this.getLoginStatus.bind(this);

        //this.service = new ApiService();
        this.state = 
            userName: '',
            password: '',
            // errorMessage: '',
            //showError: false,
            loginFailed: false
        

        apiService.on('statusChanged', this.getLoginStatus);
    

    componentWillMount() 
        apiService.on('change', this.getLoginStatus);
    

    componentWillUnmount() 
        apiService.removeListener("change", this.getLoginStatus);
    

    getLoginStatus() 
        this.setState(
            loginFailed: apiService.getLoginStatus()
        );
    

    handleUserChange(e) 
        this.setState( userName: e.target.value );
    

    handlePasswordChange(e) 
        this.setState( password: e.target.value );
    

    handleSubmit = (event) => 
        event.preventDefault();

        //this.service.login(this.state.userName, this.state.password);
        Actions.login(this.state.userName, this.state.password);
    


    render() 
        const loginFailed = this.state;
        return (
            <div className="App">
                <header className="App-header">

                    <table  className="Toolbar1">
                        <tbody>
                        <tr>
                            <td >
                                <h2>My App</h2>
                            </td>
                            <td>
                                <Button className="button">
                                    Help
                                </Button>
                            </td>
                        </tr>
                        </tbody>
                    </table>

                </header>

                <body classname="App-body">
                    <table  align="center" className="bordered spaced centered">
                        <tbody>
                        <tr>
                            <td >Welcome to ...</td>
                            <td>Ver: 1.0.0</td>
                        </tr>
                        <tr>
                            <td colSpan="2">
                                <Form onSubmit=this.handleSubmit>
                                        <TextInput
                                            className="wide"
                                            id="txtUser"
                                            labelText=""
                                            placeholder="User Name"
                                            required
                                            onChange= this.handleUserChange.bind(this) 
                                        />
                                        <br/>
                                        <TextInput
                                            className="wide"
                                            id="txtPassword"
                                            type="password"
                                            required
                                            labelText=""
                                            placeholder="Password"
                                            // pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).6,"
                                            // ...InvalidPasswordProps
                                            required
                                            onChange= this.handlePasswordChange.bind(this)
                                        />
                                        <br/>
                                        <Button type="submit" className="button wide"
                                                //onSubmit=this.handleSubmit
                                                //onClick=this.handleClick
                                        >
                                            Login
                                        </Button>
                                    <br/><br/>
                                </Form>
                            </td>
                        </tr>
                        </tbody>
                    </table>

                    /*<spane style=color: 'red'><b>Please enter valid credentials.</b></spane>*/
                    <div style=color: 'red' className="alert alert-danger centered2">
                         loginFailed ? <span color="Red"><strong>Error!</strong> Please enter valid credentials.</span> : null 
                    </div>
                </body>

                <footer>

                </footer>

            </div>
        );
    


export default Login;

【讨论】:

以上是关于react服务和组件之间如何通信?的主要内容,如果未能解决你的问题,请参考以下文章

在 React.js 中,我将如何设置一个简单的全局事件系统来在组件之间进行通信?

react组件之间通信

react native 之子组件和父组件之间的通信

React Native:组件之间的通信

React组件间通信

前端开发React 中父子组件之间的通信方式