Как правильно направить компонент, который отображает список на основе /: elementId / в URL - PullRequest
0 голосов
/ 03 мая 2019

Я в основном делаю клон диссонанса, используя rails, реакции-маршрутизатор, реаги-редукс, JavaScript и PostgreSQL.Все мои серверы и каналы рендерится, но я хочу рендерить каналы только при щелчке по серверу путем маршрутизации каналов каждого сервера в # / servers /: serverId / channel.Моя ссылка на URL работает нормально, но что-то о маршруте (я думаю) дает мне 500 внутреннюю ошибку сервера: http://localhost:3000/api/servers/NaN/channels

Я уже пробовал связываться с моим магазином, используя activeChannel: true / false, но этоКазалось, что все усложнилось, потому что это означало мутирование моего магазина.

server_index_item.jsx

import React from 'react';
import { Link, Route, NavLink } from 'react-router-dom';
import { withRouter } from 'react-router';
///
import ChannelIndexContainer from '../channels/channel_index_container';
import ChannelIndex from '../channels/channel_index';

class ServerIndexItem extends React.Component {
  render() {
    const { server, serverId, channelIds, activeChannels } = this.props;


    return (
      <div>

        <li className="server-index-item">
          <NavLink to={`/servers/${server.id}/channels`}>
            <span>{server.id}</span>
            <img className="discord-server-icon"
              src={server.image_url}
              alt={server.title} />
          </NavLink>

          <Route path="/servers/:serverId/channels"
            render={(props) => <ChannelIndexContainer {...props} serverId={serverId} channelIds={channelIds} activeChannels={activeChannels} />}></Route>
          </li>
      </div>
    );
  }

}

Channel_Index.jsx

import React from 'react';
import { Route, Link } from 'react-router-dom';
import ChannelIndexContainer from './channel_index_container';
import ChannelShow from './channel_show';

//
import TestRoute from '../test_components/test_route';

class ChannelIndex extends React.Component {
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    this.props.requestServerChannels(this.props.serverId);
  }


  render() {
    const { channels, serverId, channelIds, activeChannels } = this.props;

    const channelFilter = channels.filter(channel => {
      return channel.server_id === serverId;
    });


    return(
      <div>
        <ul>
          {channelFilter.map(channel =>
            <ChannelShow
              key={channel.id}
              channel={channel}
              activeChannels={activeChannels}
              serverId={serverId} />)}

        </ul>
      </div>
    );
  }
}

и мой контроллер каналов

class Api::ChannelsController < ApplicationController

  def index
    @channels = Channel.where("server_id = ?", params[:server_id])
  end


  def show
    @channel = Channel.find(params[:id])
  end

end

Я, когда я щелкаю по серверу, он переходит в / Servers /: ServerId / channel, как я вложил в мои маршруты, но он по-прежнему отображает каждый канал, а не только каналы для выбранного сервера., затем выдает: GET http://localhost:3000/api/servers/NaN/channels 500 (Внутренняя ошибка сервера).Заранее спасибо!

1 Ответ

0 голосов
/ 09 мая 2019

Хорошо, так что я закончил мутировать часть своего состояния, чтобы решить эту проблему, и это на самом деле сработало очень хорошо. Сначала я сделал эти действия создателей:

export const TOGGLE_SERVER = "TOGGLE_SERVER";
export const UNTOGGLE_SERVER ="UNTOGGLE_SERVER";


export const toggleServer = (server_id) => ({
  type: TOGGLE_SERVER,
  server_id
});

export const unToggleServer = () => ({
  type: UNTOGGLE_SERVER,
});

Затем я создал новый редуктор для своего магазина, который будет вложен в сущности (вместе с серверами, каналами, пользователями и т. Д.)

import {
  TOGGLE_SERVER,
  UNTOGGLE_SERVER
} from '../actions/toggle_actions';

import merge from 'lodash/merge';

const toggleReducer = (state = {}, action) => {
  switch(action.type) {
    case TOGGLE_SERVER:
      const toggledServer = { ["serverId"]: action.server_id};
      return merge({}, state, toggledServer);
    case UNTOGGLE_SERVER:
      const nextState = merge({}, state);
      delete nextState["serverId"];
      return nextState;
    default:
      return state;
  }
};
export default toggleReducer;
const mapDispatchToProps = dispatch => ({
  toggleServer: (server_id) => dispatch(toggleServer(server_id)),
  unToggleServer: () => dispatch(unToggleServer()),
});

затем в server_index_item.jsx:

class ServerIndexItem extends React.Component {
  constructor(props) {
    super(props);

  }

    handleClick(server_id) {
      this.props.unToggleServer();
      this.props.toggleServer(server_id);
    }


  render() {
    const { server, serverId, channelIds } = this.props;
    return (
      <div>

        <li className="server-index-item">
          <NavLink to={`/servers/${server.id}/channels`}>
            <span>{server.id}</span>
            <img className="discord-server-icon"
              src={server.image_url}
              alt={server.title} />
          </NavLink>
                       // here its a button for now
          <button onClick={() => this.handleClick(server.id)}>toggleTest</button>
          <ChannelIndexContainer serverId={serverId} channelIds={channelIds} />
        </li>
      </div>
    );
  }
}
export default ServerIndexItem;

И, наконец, в своем ChannelIndex я проверил, является ли channel.server_id === activeServerId и отображать ли каналы, если это правда. Мой первый пост, поэтому я немного не уверен, что моя первоначальная проблема не была разработана должным образом, поэтому я надеюсь, что мой ответ на мой собственный вопрос (с другим решением) компенсирует это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...