通过ID

时间:2019-05-20 08:30:51

标签: node.js reactjs redux

我正在构建多用户语言词典,并且一直坚持按ID编辑单词。我正在使用 React-Redux-NodeJS堆栈。我想我不太了解redux,尤其是 actions和reducers 。因此,如果您给我一些指导,我将非常高兴。以下是我的代码文件。

Word API (Node JS)

// @route  Put api/words/:id
// @desc   Update a word by id
// @access Private

router.put(
  '/:id',
  passport.authenticate('jwt', { session: false }),
  (req, res) => {
    const { errors, isValid } = validateWordInput(req.body);

    // Check validation
    if (!isValid) {
      // Return any errors
      return res.status(400).json(errors);
    }
    Profile.findOne({ user: req.user.id }).then(profile => {
      Word.findById(req.params.id)
        .then(word => {
          // Check for word owner
          if (word.user.toString() !== req.user.id) {
            return res
              .status(401)
              .json({ notauthorized: 'User not authorized' });
          }

          const wordID = req.params.id;
          const wordInput = req.body;

          // Update
          Word.findByIdAndUpdate(
            { _id: wordID },
            { $set: wordInput },
            { returnOriginal: false },
            (err, word) => {
              if (err) {
                console.log(err);
              }
            }
          ).then(word => res.json(word));
        })
        .catch(err => res.status(404).json({ nowordfound: 'No word found' }));
    });
  }
);

编辑单词形式(反应)

import React, { Component } from 'react';
import { Link, withRouter } from 'react-router-dom';
import TextFieldGroup from '../common/TextFieldGroup';
import SelectListGroup from '../common/SelectListGroup';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { addWord, updateWord } from '../../actions/wordActions';
import isEmpty from '../../validation/is-empty';

class EditWord extends Component {
  constructor(props) {
    super(props);
    this.state = {
      ugrWordCyr: '',
      rusTranslation: '',
      example: '',
      exampleTranslation: '',
      origin: '',
      sphere: '',
      see: '',
      lexis: '',
      grammar: '',
      partOfSpeech: '',
      style: '',
      errors: {}
    };
    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
    this.onCheck = this.onCheck.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.errors) {
      this.setState({ errors: nextProps.errors });
    }

    if (nextProps.words.words) {
      const words = nextProps.words.words;

      // if profile field does not exist make empty string
      words.ugrwordsCyr = !isEmpty(words.ugrwordsCyr) ? words.ugrwordsCyr : '';
      words.rusTranslation = !isEmpty(words.rusTranslation)
        ? words.rusTranslation
        : '';
      words.example = !isEmpty(words.example) ? words.example : '';
      words.exampleTranslation = !isEmpty(words.exampleTranslation)
        ? words.exampleTranslation
        : '';
      words.origin = !isEmpty(words.origin) ? words.origin : '';
      words.sphere = !isEmpty(words.sphere) ? words.sphere : '';
      words.see = !isEmpty(words.see) ? words.see : {};
      words.lexis = !isEmpty(words.lexis) ? words.lexis : {};
      words.grammar = !isEmpty(words.grammar) ? words.grammar : {};
      words.see = !isEmpty(words.see) ? words.see : {};
      words.style = !isEmpty(words.style) ? words.style : {};

      // Set component fields state
      this.setState({
        ugrWordCyr: words.ugrWordCyr,
        rusTranslation: words.rusTranslation,
        example: words.example,
        exampleTranslation: words.exampleTranslation,
        origin: words.origin,
        lexis: words.lexis,
        grammar: words.grammar,
        see: words.see,
        partOfSpeech: words.partOfSpeech
      });
    }
  }

  onSubmit(e) {
    e.preventDefault();
    const wordData = {
      ugrWordCyr: this.state.ugrWordCyr,
      rusTranslation: this.state.rusTranslation,
      example: this.state.example,
      exampleTranslation: this.state.exampleTranslation,
      origin: this.state.origin,
      sphere: this.state.sphere,
      see: this.state.see,
      lexis: this.state.lexis,
      grammar: this.state.grammar,
      partOfSpeech: this.state.partOfSpeech,
      style: this.state.style
    };
    this.props.updateWord(wordData, this.props.history);
  }

  onChange(e) {
    this.setState({ [e.target.name]: e.target.value });
  }

  onCheck(e) {
    this.setState({
      current: !this.state.current
    });
  }
  render() {
    const { errors } = this.state;
    const sphereOptions = [
      { label: 'Выберите сферу употребления слова', value: 0 },
      { label: 'Анатомия', value: 'Анатомия' },
      { label: 'Археология', value: 'Археология' },
      { label: 'Архитектура', value: 'Архитектура' },
      { label: 'Астрономия', value: 'Астрономия' },
      { label: 'Биология', value: 'Биология' },
      { label: 'Ботаника', value: 'Ботаника' },
      { label: 'Бухгалтерия', value: 'Бухгалтерия' },
      { label: 'Ветеренария', value: 'Ветеренария' },
      { label: 'География', value: 'География' },
      { label: 'Диалектизм', value: 'Диалектизм' },
      { label: 'Дипломатический термин', value: 'Дипломатический термин' },
      { label: 'Железнодорожное дело', value: 'Железнодорожное дело' },
      { label: 'Зоология', value: 'Зоология' },
      { label: 'Исторический термин', value: 'Исторический термин' },
      { label: 'Кулинария', value: 'Кулинария' },
      { label: 'Лингвистика', value: 'Лингвистика' },
      { label: 'Математика', value: 'Математика' },
      { label: 'Медицина', value: 'Медицина' },
      { label: 'Религия', value: 'Религия' },
      { label: 'Физкультура и спорт', value: 'Физкультура и спорт' },
      { label: 'Сельзкое хозяйство', value: 'Сельзкое хозяйство' },
      { label: 'Фармацептический термин', value: 'Фармацептический термин' },
      { label: 'Физика', value: 'Физика' },
      { label: 'Физиология', value: 'Физиология' },
      { label: 'Фольклор', value: 'Фольклор' },
      { label: 'Химия', value: 'Химия' },
      { label: 'Экономика', value: 'Экономика' },
      { label: 'Этнография', value: 'Этнография' },
      { label: 'Юридический термин', value: 'Юридический термин' }
    ];
    const originOptions = [
      { label: 'Выберите вариант происхождения слова', value: 0 },
      { label: 'Арабское слово', value: 'Арабское слово' },
      { label: 'Китайское слово', value: 'Китайское слово' },
      { label: 'Русское слово', value: 'Русское слово' },
      { label: 'Монгольский язык', value: 'Монгольский язык' },
      { label: 'Персидское слово', value: 'Персидское слово' },
      { label: 'Уйгурское слово', value: 'Уйгурское слово' },
      { label: 'Китайско-Уйгурское слово', value: 'Китайско-Уйгурское слово' },
      {
        label: 'Монгольско-Уйгурское слово',
        value: 'Могольско-Уйгурское слово'
      },
      { label: 'Русско-уйгурское слово', value: 'Русско-уйгурское слово' },
      { label: 'Арабско-Уйгурское слово', value: 'Арабско-Уйгурское слово' },
      { label: 'Персидско-Уйгурское слово', value: 'Персидско-Уйгурское слово' }
    ];

    const lexisOptions = [
      { label: 'Выберите лексику слова', value: 0 },
      { label: 'В переносном значении', value: 'В переносном значении' },
      { label: 'Малоупотребительно', value: 'Малоупотребительно' },
      { label: 'Поговорка', value: 'Поговорка' },
      { label: 'Пословица', value: 'Пословица' },
      { label: 'В разных значениях', value: 'В разных значениях' },
      { label: 'В прямом значении', value: 'В прямом значении' }
    ];

    const styleOptions = [
      { label: 'Выберите стиль слова', value: 0 },
      { label: 'Бранное слово', value: 'Бранное слово' },
      { label: 'Поэтическое слово', value: 'Поэтическое слово' },
      { label: 'Разговорное слово', value: 'Разговорное слово' },
      { label: 'Книжный стиль', value: 'Книжный стиль' },
      { label: 'Неодобрительно', value: 'Неодобрительно' },
      { label: 'В ироничном смысле', value: 'В ироничном смысле' }
    ];

    const partOfSpeechOptions = [
      { label: 'Выберите часть речи к которому принадлежит слово', value: 0 },
      { label: 'Вводное слово', value: 'Вводное слово' },
      {
        label: 'Вопросительное местоимение',
        value: 'Вопросительное местоимение'
      },
      { label: 'Вопросительная частица', value: 'Вопросительная частица' },
      { label: 'Глагол', value: 'Глагол' },
      {
        label: 'Количественное числительное',
        value: 'Количественное числительное'
      },
      {
        label: 'Существительное',
        value: 'Существительное'
      },
      {
        label: 'Порядковое числительное',
        value: 'Порядковое числительное'
      },
      {
        label: 'Междометие',
        value: 'Междометие'
      },
      {
        label: 'Звукоподражание',
        value: 'Звукоподражание'
      },
      {
        label: 'Личное местоимение',
        value: 'Личное местоимение'
      },
      {
        label: 'Местоимение',
        value: 'Местоимение'
      },
      {
        label: 'Отрицательная частица',
        value: 'Отрицательная частица'
      },
      {
        label: 'Имя прилагательное',
        value: 'Имя прилагательное'
      },
      {
        label: 'Причастие',
        value: 'Причастие'
      },
      {
        label: 'Разделительный союз',
        value: 'Разделительный союз'
      },
      {
        label: 'Собирательное существительное',
        value: 'Собирательное существительное'
      },
      {
        label: 'Соединительный союз',
        value: 'Соединительный союз'
      },
      {
        label: 'Указательное местоимение',
        value: 'Указательное местоимение'
      },
      {
        label: 'Число',
        value: 'Число'
      },
      {
        label: 'Усилительная частица',
        value: 'Усилительная частица'
      },
      {
        label: 'Утвердительная частица',
        value: 'Утвердительная частица'
      }
    ];

    const grammarOptions = [
      { label: 'Выберите грамматику слова', value: 0 },
      { label: 'Имя действия', value: 'Имя действия' },
      { label: 'Лицо глагола', value: 'Лицо глагола' },
      { label: 'Взаимный залог', value: 'Взаимный залог' },
      { label: 'Возвратный залог', value: 'Возвратный залог' },
      { label: 'Грамматика', value: 'Грамматика' },
      { label: 'Дательный падеж', value: 'Дательный падеж' },
      { label: 'Деепречастие', value: 'Деепречастие' },
      { label: 'Единственное число', value: 'Единственное число' },
      { label: 'Множественное число', value: 'Множественное число' },
      { label: 'Многократный вид глагола', value: 'Многократный вид глагола' },
      { label: 'Однократный вид глагола', value: 'Однократный вид глагола' },
      { label: 'Направительный падеж', value: 'Направительный падеж' },
      { label: 'Сравнительная степень', value: 'Сравнительная степень' },
      { label: 'Страдательный залог', value: 'Страдательный залог' },
      { label: 'Родительный падеж', value: 'Родительный падеж' },
      { label: 'Уменьшительная форма', value: 'Уменьшительная форма' }
    ];
    return (
      <div className="add-word">
        <div className="container">
          <div className="row">
            <div className="col-md-8 m-auto">
              <Link to="/my-words" className="btn btn-light">
                Go Back
              </Link>
              <h1 className="display-4 text-center">Edit Word</h1>
              <form onSubmit={this.onSubmit}>
                <TextFieldGroup
                  placeholder="Бала"
                  info="Введите слово на уйгурском"
                  name="ugrWordCyr"
                  value={this.state.ugrWordCyr}
                  onChange={this.onChange}
                  error={errors.ugrWordCyr}
                />
                <TextFieldGroup
                  placeholder="Ребенок"
                  info="Введите слово на русском"
                  name="rusTranslation"
                  value={this.state.rusTranslation}
                  onChange={this.onChange}
                  error={errors.rusTranslation}
                />
                <div className="form-check mb-form">
                  <input
                    type="checkbox"
                    className="form-check-input"
                    name="see"
                    value={this.state.see}
                    onChange={this.onCheck}
                    id="see"
                  />
                  <label htmlFor="see">Смотри</label>
                </div>
                <TextFieldGroup
                  placeholder=""
                  info="Введите пример предложения на уйгурском"
                  name="example"
                  value={this.state.example}
                  onChange={this.onChange}
                  error={errors.example}
                />
                <TextFieldGroup
                  placeholder=""
                  info="Введите перевод примерного предложения на русском"
                  name="exampleTranslation"
                  value={this.state.exampleTranslation}
                  onChange={this.onChange}
                  error={errors.exampleTranslation}
                />
                <h6>Происхождение слова</h6>
                <SelectListGroup
                  placeholder="Арабское"
                  name="origin"
                  value={this.state.origin}
                  onChange={this.onChange}
                  error={errors.origin}
                  options={originOptions}
                />
                <h6>Сфера употребления слова</h6>
                <SelectListGroup
                  placeholder="Физика"
                  name="sphere"
                  value={this.state.sphere}
                  onChange={this.onChange}
                  error={errors.sphere}
                  options={sphereOptions}
                />
                <h6>Лексика слова</h6>
                <SelectListGroup
                  placeholder=""
                  name="lexis"
                  value={this.state.lexis}
                  onChange={this.onChange}
                  error={errors.lexis}
                  options={lexisOptions}
                />
                <h6>Стиль слова</h6>
                <SelectListGroup
                  placeholder=""
                  name="style"
                  value={this.state.style}
                  onChange={this.onChange}
                  error={errors.style}
                  options={styleOptions}
                />
                <h6>Часть речи</h6>
                <SelectListGroup
                  placeholder=""
                  name="partOfSpeech"
                  value={this.state.partOfSpeech}
                  onChange={this.onChange}
                  error={errors.partOfSpeech}
                  options={partOfSpeechOptions}
                />
                <h6>Грамматика слова</h6>
                <SelectListGroup
                  placeholder=""
                  name="grammar"
                  value={this.state.grammar}
                  onChange={this.onChange}
                  error={errors.grammar}
                  options={grammarOptions}
                />
                <input
                  type="submit"
                  value="submit"
                  className="btn btn-info btn-block mt-4"
                />
              </form>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

EditWord.propTypes = {
  addWord: PropTypes.func.isRequired,
  updateWord: PropTypes.func.isRequired,
  errors: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  errors: state.errors,
  word: state.words
});

export default connect(
  mapStateToProps,
  { addWord, updateWord }
)(withRouter(EditWord));

文字动作(Redux)

import axios from 'axios';
import { GET_ERRORS, GET_WORDS_BY_USER, ADD_WORD, UPDATE_WORD } from './types';

export const addWord = (wordData, history) => dispatch => {
  axios
    .post('/api/words', wordData)
    .then(res => {
      dispatch({
        type: ADD_WORD,
        payload: res.data
      });
      history.push('/dashboard');
    })
    .catch(err =>
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      })
    );
};

export const getWordsByUser = () => dispatch => {
  axios
    .get('/api/words')
    .then(res =>
      dispatch({
        type: GET_WORDS_BY_USER,
        payload: res.data
      })
    )
    .catch(err =>
      dispatch({
        type: GET_WORDS_BY_USER,
        payload: null
      })
    );
};

**export const updateWord = id => dispatch => {
  axios
    .get('/api/words/:id')
    .then(res =>
      dispatch({
        type: UPDATE_WORD,
        payload: res.data
      })
    )
    .catch(err =>
      dispatch({
        type: UPDATE_WORD,
        payload: null
      })
    );
};**

Word Reducer

import { GET_WORDS_BY_USER, ADD_WORD, UPDATE_WORD } from '../actions/types';

const initialState = {
  words: [],
  word: {},
  loading: false
};

export default function(state = initialState, action) {
  switch (action.type) {
    case ADD_WORD:
      return {
        ...state,
        words: [action.payload, ...state.words]
      };
    case GET_WORDS_BY_USER:
      return {
        ...state,
        words: action.payload,
        loading: false
      };
    case UPDATE_WORD:
      return {
        ...state,
        word: action.payload
      };
    default:
      return state;
  }
}

0 个答案:

没有答案