首页 文章

是否可以在Redux / React中分离组件的表示和逻辑?

提问于
浏览
0

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

问题是 - 它是否真实,我们无法将它们分开以使我们的代码更清晰?

例如来自官方redux.js.org docs的一些组件 . 因此,逻辑和压力在一起,它看起来并不那么好和清晰:

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

附:我也看到了这个问题:Separating presentational and logic components react/redux,这是不一样的 .

UPD:我将逻辑分成onSubmit模块和组件表示 . 但是>现在我得到一个错误 - TypeError:不能将一个类作为函数调用:

/* 介绍 */

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;

1 回答

  • 4

    从您提供的相同文档:

    有时很难判断某些组件应该是表示组件还是容器 . 例如,有时形式和功能实际上是耦合在一起的,例如在这个小组件的情况下:AddTodo是一个带有“Add”按钮的输入字段
    从技术上讲,我们可以将它分成两个部分,但现阶段可能还为时过早 . 将表示和逻辑混合在一个非常小的组件中是很好的 . 随着它的增长,如何分割它会更加明显,所以我们会把它混合起来 .

    所以是的,你是对的,最好将我们的展示和容器组件分开,并且如你所述,它在文档中得到了很好的解释 . 你给出的例子只是一个例外 .

    在这里你可以如何分离组件:

    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;
    

    我强烈建议你在Dan Abramov(Redux的创造者)的Egghead上观看Redux视频 . 观看这些视频后,您将从头开始了解Redux的逻辑 . 有两个部分,看两个部分 . 在我学习Redux的过程中,我观看了这些并编写了所有代码 . 之后我创建了一个回购:https://github.com/devserkan/react-with-idiomatic-redux

    你可以克隆这个回购并按你的意愿玩 .

相关问题