Связать checkbox и элемент списка li ReactJs

169
01 июля 2019, 03:30

Пытаюсь повторить вот этот todo проект: введите сюда описание ссылки

Как можно ГРАМОТНО связать заметку вместе с radio-button, чтобы когда я на него нажимал заметка зачеркивалась. Подскажите react-овское решение вопроса.

Answer 1

Вариант №1:

import React from 'react'; 
 
export default class MyComponent extends React.Component { 
 
  constructor() { 
    super(); 
 
    this.state = { 
      crossedOut: false 
    } 
     
    this.toggleCrossedOut = this.toggleCrossedOut.bind(this); 
  } 
   
  toggleCrossedOut() { 
    this.setState({ 
      crossedOut: !this.state.crossedOut 
    }) 
  } 
 
  render () { 
    const { crossedOut } = this.state; 
    return ( 
      <label 
        className={crossedOut? "crossed-out": ""} 
      > 
        Some text 
        <input type="checkbox" onChange={this.toggleCrossedOut} /> 
      </label> 
    ) 
  } 
}

Вариант №2 (с использованием npm пакета classnames)

import React from 'react'; 
import classNames from "classnames"; 
 
export default class MyComponent extends React.Component { 
 
  constructor() { 
    super(); 
 
    this.state = { 
      crossedOut: false 
    } 
     
    this.toggleCrossedOut = this.toggleCrossedOut.bind(this); 
  } 
   
  toggleCrossedOut() { 
    this.setState({ 
      crossedOut: !this.state.crossedOut 
    }) 
  } 
 
  render () { 
    const { crossedOut } = this.state; 
    return ( 
      <label 
        className={classNames({ 
          "crossed-out": crossedOut 
        })} 
      > 
        Some text 
        <input type="checkbox" onChange={this.toggleCrossedOut} /> 
      </label> 
    ) 
  } 
}

Answer 2

Вот видео от Dan Abramov. Нужно будет зарегистрироваться. Ниже код, если лень регистрироваться и смотреть.

const todo = (state, action) => { 
  switch (action.type) { 
    case "ADD_TODO": 
      return { 
        id: action.id, 
        text: action.text, 
        completed: false 
      }; 
    case "TOGGLE_TODO": 
      if (state.id !== action.id) { 
        return state; 
      } 
 
      return { 
        ...state, 
        completed: !state.completed 
      }; 
    default: 
      return state; 
  } 
}; 
const todos = (state = [], action) => { 
  switch (action.type) { 
    case "ADD_TODO": 
      return [...state, todo(undefined, action)]; 
    case "TOGGLE_TODO": 
      return state.map(t => todo(t, action)); 
    default: 
      return state; 
  } 
}; 
 
const visibilityFilter = (state = "SHOW_ALL", action) => { 
  switch (action.type) { 
    case "SET_VISIBILITY_FILTER": 
      return action.filter; 
    default: 
      return state; 
  } 
}; 
 
const { combineReducers } = Redux; 
const todoApp = combineReducers({ 
  todos, 
  visibilityFilter 
}); 
 
const { createStore } = Redux; 
const store = createStore(todoApp); 
 
const { Component } = React; 
 
const FilterLink = ({ 
  filter, 
  currentFilter, 
  children 
}) => { 
  if (filter === currentFilter) { 
    return ( 
      <span>{children}</span> 
    ); 
  } 
  return ( 
    <a 
      href="#" 
      onClick={e => { 
        e.preventDefault(); 
        store.dispatch({ 
          type: "SET_VISIBILITY_FILTER", 
          filter 
        }); 
      }} 
    > 
      {children} 
    </a> 
  ); 
}; 
 
const getVisibleTodos = (todos, filter) => { 
  switch (filter) { 
    case "SHOW_ALL": 
      return todos; 
    case "SHOW_COMPLETED": 
      return todos.filter(t => t.completed); 
    case "SHOW_ACTIVE": 
      return todos.filter(t => !t.completed); 
  } 
}; 
let nextTodoId = 0; 
 
class TodoApp extends Component { 
  render() { 
    const { 
      todos, 
      visibilityFilter 
    } = this.props; 
    const visibleTodos = getVisibleTodos( 
      todos, 
      visibilityFilter 
    ); 
    return ( 
      <div> 
        <input 
          ref={node => { 
            this.input = node; 
          }} 
        /> 
        <button 
          onClick={() => { 
            store.dispatch({ 
              type: "ADD_TODO", 
              text: this.input.value, 
              id: nextTodoId++ 
            }); 
            this.input.value = ""; 
          }} 
        > 
          Add Todo 
        </button> 
        <ul> 
          {visibleTodos.map(todo => ( 
            <li 
              key={todo.id} 
              onClick={() => { 
                store.dispatch({ 
                  type: "TOGGLE_TODO", 
                  id: todo.id 
                }); 
              }} 
              style={{ 
                textDecoration: todo.completed ? "line-through" : "none" 
              }} 
            > 
              {todo.text} 
            </li> 
          ))} 
        </ul> 
        <p> 
          Show:  
          {'  '}  
          <FilterLink  
             filter="SHOW_ALL" 
             currentFilter={visibilityFilter}  
          > 
            All 
          </FilterLink> 
          {'  '}  
          <FilterLink  
             filter="SHOW_COMPLETED" 
             currentFilter={visibilityFilter}  
          > 
            Completed 
          </FilterLink> 
          {'  '}  
          <FilterLink  
             filter="SHOW_ACTIVE" 
             currentFilter={visibilityFilter}  
          > 
            Active 
          </FilterLink> 
        </p> 
      </div> 
    ); 
  } 
} 
const render = () => { 
  ReactDOM.render( 
    <TodoApp {...store.getState()} />, 
    document.getElementById("root") 
  ); 
}; 
 
store.subscribe(render); 
render();
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.min.js"></script> 
<div id="root"></div>

READ ALSO
Как расположить div-ы с помощью bootstrap

Как расположить div-ы с помощью bootstrap

нужно сделать вот такой макет

143
Появление элемента при условии

Появление элемента при условии

Нужно чтобы появилась кнопка при условии, что если хотя бы один из параграфов в блоке имеет классclicked

156
Анимация новогодней ёлочки

Анимация новогодней ёлочки

Хорошо бы поднять настроение себе и другимКопировать и рассылать открыточки с красивыми картинками и гифками, скаченными из сети, уже как-то...

114
Подключение jQuery после скрипта

Подключение jQuery после скрипта

Если подключать jquery до вывода формы все работает:

139