是否可以在 Redux/React 中分离组件的表示和逻辑? [英] Is it possible to separate presentation and logic for component in Redux/React?

查看:51
本文介绍了是否可以在 Redux/React 中分离组件的表示和逻辑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如 redux 的官方文档所示 -> https://redux.js.org/basics/usage-with-react,逻辑和预设必须捆绑在一起.

问题是 - 我们不能将它们分开以使我们的代码更清晰,这是真的吗?

例如来自官方 redux.js.org 文档的一些组件.所以,逻辑和预制放在一起,看起来不太好和清晰:

从 'react' 导入 React从'react-redux'导入{连接}从 '../actions' 导入 { addTodo }让 AddTodo = ({ dispatch }) =>{让输入返回 (<div><表格onSubmit={e =>{e.preventDefault()如果 (!input.value.trim()) {返回}dispatch(addTodo(input.value))输入值 = ''}}><输入参考={节点=>{输入 = 节点}}/><按钮类型=提交">添加待办事项</表单>

)}AddTodo = connect()(AddTodo)导出默认 AddTodo

附言我也看到了这个问题:分离表示和逻辑组件 react/redux,这不一样.

<块引用>

更新:我将逻辑分为 onSubmit 模块和组件呈现.但是 > 现在我收到一个错误 - TypeError:无法将类作为函数调用 :

/* 演示文稿 */

从'react'导入React;从'react-redux'导入{连接};从'../../Actions/AddTodo'导入AddTodo从'../../Modules/handleClick' 导入 addTodo类 AddTodos 扩展 React.Component{componentDidMount() {console.log(addTodo());//用于测试.获取类型错误:无法将类作为函数调用"}使成为() {返回 (<表格><input type="text" placeholder="你的文字"/><button type="submit">添加待办事项</button></表单>);}}导出默认的 AddTodos;

/* 提交模块 */

import { connect } from 'react-redux';从 '../Actions/AddTodo' 导入 AddTodo让 addTodo = ({ dispatch }) =>{如果(document.readyState === '完成'){let form = document.querySelector('form');form.addEventListener('submit', handleClick);函数 handleClick(e) {e.preventDefault();让 input = document.querySelector('input');dispatch(AddTodo(input.value));输入值 = '';}}}addTodo = connect()(addTodo);导出默认 addTodo;

解决方案

来自您提供的同一文档:

<块引用>

有时很难判断某个组件是否应该是表示组件或容器.例如,有时形成和功能真的耦合在一起,例如在这种情况下小组件:

AddTodo 是一个带有添加"按钮的输入框

技术上我们可以把它分成两个部分,但它可能太在这个阶段早期.将表示和逻辑混合在一个非常小的组件.随着它的成长,它将更加明显地把它分开,所以我们把它混合起来.

所以,是的,您是对的,最好将我们的展示组件和容器组件分开,正如您所说,文档中对此进行了很好的解释.你举的例子只是一个例外.

这里如何分离组件:

添加待办事项

从react"导入React;从prop-types"导入 PropTypes;从react-redux"导入{连接};import { addTodo } from "../actions";从./AddTodoForm"导入AddTodoForm;const AddTodo = (道具) =>{const handleAddTodo = todo =>props.dispatch( addTodo( todo ) );返回 (<AddTodoForm addTodo={handleAddTodo}/>);};导出默认连接()( AddTodo );

AddTodoForm

从react"导入React;const AddTodoForm = ( props ) =>{让输入;const handleClick = () =>{props.addTodo( input.value );input.value = "";};返回 (<div><输入ref={(节点)=>{输入 = 节点;}}/><按钮onClick={handleClick}>添加待办事项

);};导出默认的 AddTodoForm;

我强烈建议您观看 Dan Abramov(Redux 的创建者)在 Egghead 上的 Redux 视频.看完这些视频,你就会从头了解 Redux 的逻辑.有两部分,两部分都看.在我学习 Redux 时,我观看了这些并在观看的同时编写了所有代码.之后我创建了一个仓库:https://github.com/devserkan/react-with-惯用的redux

您可以克隆此存储库并随心所欲地玩.

As showed in official docs of redux -> https://redux.js.org/basics/usage-with-react, the logic and presetation must been tied together.

The question is - is it real, that we cannot separate them to make our code more clear?

For example some component from official redux.js.org docs. So, the logic and pres are together in it and it's not looking so good and clear:

import React from 'react'
import { connect } from 'react-redux'
import { addTodo } from '../actions'
 
let AddTodo = ({ dispatch }) => {
  let input
 
  return (
    <div>
      <form
        onSubmit={e => {
          e.preventDefault()
          if (!input.value.trim()) {
            return
          }
          dispatch(addTodo(input.value))
          input.value = ''
        }}
      >
        <input
          ref={node => {
            input = node
          }}
        />
        <button type="submit">
          Add Todo
        </button>
      </form>
    </div>
  )
}
AddTodo = connect()(AddTodo)
 
export default AddTodo

P.S. Also I saw this question: Separating presentational and logic components react/redux , this is not the same.

UPD: I had separate the logic into onSubmit module and component presentation. But > for now I get an error - TypeError: Cannot call a class as a function :

/* PRESENTATION */

import React from 'react';
import { connect } from 'react-redux';
import AddTodo from '../../Actions/AddTodo'
import addTodo from '../../Modules/handleClick'

class AddTodos extends React.Component{    
    componentDidMount() {
        console.log(addTodo()); // for test. Get "TypeError: Cannot call a class as a function"
    }

    render() {
        return (
            <form>
                <input type="text" placeholder="Your text" />
                <button type="submit">Add todos</button>
            </form>
        );  
    }
}

export default AddTodos;

/* ONSUBMIT MODULE */

import { connect } from 'react-redux';
import AddTodo from '../Actions/AddTodo'

let addTodo = ({ dispatch }) => {
    if (document.readyState === 'complete') {
        let form = document.querySelector('form');
        form.addEventListener('submit', handleClick);

        function handleClick(e) {
            e.preventDefault();

            let input = document.querySelector('input');    
            dispatch(AddTodo(input.value));

            input.value = '';
        }
    }
}

addTodo = connect()(addTodo);

export default addTodo;

解决方案

From the same documentation you gave:

Sometimes it's hard to tell if some component should be a presentational component or a container. For example, sometimes form and function are really coupled together, such as in the case of this tiny component:

AddTodo is an input field with an "Add" button

Technically we could split it into two components but it might be too early at this stage. It's fine to mix presentation and logic in a component that is very small. As it grows, it will be more obvious how to split it, so we'll leave it mixed.

So yes you are right, it is better to separate our presentational and container components and it is explained very well in the documentation as you stated. The example you gave is just an exception.

Here how you can separate the components:

AddTodo

import React from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { addTodo } from "../actions";
import AddTodoForm from "./AddTodoForm";

const AddTodo = ( props ) => {
    const handleAddTodo = todo => props.dispatch( addTodo( todo ) );

    return (
        <AddTodoForm addTodo={handleAddTodo} />
    );
};

export default connect()( AddTodo );

AddTodoForm

import React from "react";

const AddTodoForm = ( props ) => {
    let input;

    const handleClick = () => {
        props.addTodo( input.value );
        input.value = "";
    };


    return (
        <div>
            <input
                ref={( node ) => {
                    input = node;
                }}
            />
            <button
                onClick={handleClick}
            >
    Add Todo
            </button>
        </div>
    );
};

export default AddTodoForm;

I strongly advise you to watch Redux videos on Egghead from Dan Abramov (creator of Redux). You will understand the logic of Redux from scratch after watching those videos. There are two parts, watch both parts. While I studying Redux I watched those and write all the codes while watching. After that I created a repo: https://github.com/devserkan/react-with-idiomatic-redux

You can clone this repo and play as you wish.

这篇关于是否可以在 Redux/React 中分离组件的表示和逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆