javascript - 如何根据 URL 中的 /:elementId/ 正确路由呈现列表的组件
问题描述
我基本上是在使用 rails、react-router、react-redux、JavaScript 和 PostgreSQL 制作一个不和谐的克隆。我的服务器和频道都呈现,但我只想通过将每个服务器的频道路由到 #/servers/:serverId/channels 来呈现频道。我的 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/channels ,这就是我将它嵌套在路由中的方式,但它仍然呈现每个通道,而不仅仅是所单击服务器的通道,然后抛出:GET http://localhost:3000/api/servers/NaN/channels 500(内部服务器错误)。提前致谢!
解决方案
好的,所以我最终改变了我的部分状态来解决这个问题,它实际上效果很好。首先,我制作了这些动作创建者:
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 是否为真,如果为真则渲染频道。我的第一个松弛帖子,所以我有点不确定我的原始问题是否没有正确阐述,所以我希望我对自己问题的回答(使用不同的解决方案)可以弥补它。
推荐阅读
- php - Laravel 6.x 新密码。确认中间件不适用于自定义防护
- javascript - 使用 Javascript 过滤嵌套数组
- facebook - 如何通过 api 在沙箱内创建 facebook 广告?
- python - 使用 scipy 的 ode 求解器调整粘度
- xslt - 删除具有与其他元素的属性值匹配的属性值的元素
- python - 如何从对数图中删除科学记数法?
- python - TypeError:“对象”类型的参数不可迭代
- laravel - 将数据添加到 Laravel 集合
- intellij-idea - 我可以使用 Intellij Community Edition 创建 JEE Web 应用程序吗?
- cmd - 如何将 Windows 10 cmd 恢复为默认属性设置