Javascript 在React/Redux中更改url

Javascript 在React/Redux中更改url,javascript,reactjs,redux,react-router,antd,Javascript,Reactjs,Redux,React Router,Antd,我正在尝试用React和Redux(DVA)构建一个应用程序。它使用Ant.Design作为主要框架。我试图在用户点击一个按钮时更改URL,很明显,将URL更改“绑定”到一个动作,这样,如果用户直接访问该URL,他就可以得到他想要的 现在,这是我在我的组件中的一个函数 const { dispatch, match } = this.props; dispatch(routerRedux.push('/f/' + record.id)); 这是我唯一能制作的东西。它正确地更改了url,但没有将

我正在尝试用React和Redux(DVA)构建一个应用程序。它使用Ant.Design作为主要框架。我试图在用户点击一个按钮时更改URL,很明显,将URL更改“绑定”到一个动作,这样,如果用户直接访问该URL,他就可以得到他想要的

现在,这是我在我的组件中的一个函数

const { dispatch, match } = this.props;
dispatch(routerRedux.push('/f/' + record.id));
这是我唯一能制作的东西。它正确地更改了url,但没有将url与特定行为绑定,使其完全无用


如何使用操作链接URL

如果希望基于URL触发操作,则需要使用
react router
路由一个组件,然后该组件执行所需操作。在这种情况下,最好访问其他URL,从浏览器的历史记录中删除操作URL

典型的路由器定义可能如下所示(摘自):


注意使用
replace
代替
push
。这意味着,当用户访问此URL时,他们的操作将被执行,并最终获得
/success
。但如果他们单击“上一步”按钮,他们将不会再次访问此URL并再次运行操作。

出于隐私原因,我无法将代码放在Codepen上。但这里有一个摘录:

路由器.js

...
},
'/users': {
  component: dynamicWrapper(app, ['rule'], () => import('../routes/users')),
},
'/f/:userID': {
  component: dynamicWrapper(app, ['rule'], () => import('../routes/users')),
},
...
js(包含LeftPanel和RightPanel的主要组件)

import React,{PureComponent}来自'React';
从“dva”导入{connect};
从“antd”导入{Row,Col,Card,List,Divider,Badge,Select,Radio,Input,Popover,Button,Table,Spin};
从“/RightPanel”导入RightPanel;
从“/LeftPanel”导入LeftPanel;
从“dva/路由器”导入{routerRedux,Route,Switch};
导入'font-awesome/css/font-awesome.min.css';
从“反应淡入”导入淡入;
@连接(({rule,loading})=>({rule,loading:loading.models.rule}))
导出默认类用户扩展React.Component{
建造师(道具){
超级(道具)
此.state={
所选用户:[],
defaultView:true,
isLoadingNow:错误,
选定的箭头键:[],
makeEmpty:false,
搜索结果:[]
}
}
选择行=(记录)=>{
const{dispatch,match}=this.props;
分派(routerRedux.replace({pathname:'/f/'+record.id}));
this.setState({isLoadingNow:true,selectedRowKeys:record.key})
设置超时(()=>{
这是我的国家({
isLoadingNow:错误,
defaultView:false,
所选用户:记录
})
}, 75)
}
componentDidMount(){
const{dispatch,match}=this.props;
派遣({
键入:“规则/获取”
});
if(match.params.userID==未定义){
//无所事事
}else if(match.params.userID){
var result=this.props.rule.data.list.filter(函数(obj){
返回obj.id==match.params.userID;
});
this.selectRow.bind(此,结果[0])
}
}
render(){
const{selectedRowKeys}=this.state;
常量行选择={
选择的箭头键,
类型:“收音机”
};
const{rule:{data},load}=this.props;
返回(
);
}
}
leftPanel.js(负责显示链接列表,用户将在其中单击一个链接,这将做两件事:
-相应地更改url
-在RightPanel.js上显示特定数据)

从“React”导入React;
从“antd”导入{表,卡};
从“./index.less”导入样式;
//导入'font-awesome/css/font-awesome.min.css';
从“antd”导入{Row,Col,List,Divider,Badge,Select,Radio,Input,Popover,Button};
var力矩=要求的(‘力矩’);
类LeftPanel扩展了React.Component{
建造师(道具){
超级(道具)
此.state={
所选行索引:未定义
}
}   
HandleChangeStyleOnElectrow(索引){
这是我的国家({
所选行索引:索引
},console.log(this.state.selected_row_index))
}
可美化(原始数据){
var-prettyRows=[];
原始数据.map((项目,索引)=>
推(
{item.user_name}{item.user_age}
{矩(item.user\u color).format('HH:MM')}·{矩(item.user\u order).format('HH:MM')}
{item.user_family}
{力矩(item.user_height).format('MMMM D')}
{(item.status==“进行中”)?:}
)
);
返回窗口;
}
render(){
const stylesSelectedRow={“背景”:“rgba(155155,0.05)”,“盒影”:“0 0 5px 0#4A90E2”,“变换”:“比例(1.01)”;
const{dataSource}=this.props;
返回(
{数据源&&
({this.state.selected_row_index==index?null:this.props.selectRow(this.props.dataSource[index]);this.handlechangestyleonsetrow(index)}style={this.state.selected_row_index==index?stylesSelectedRow:null}className={styles.userRows}>{item}
/>
}
)
}
}
导出默认左面板;
最后是RightPanel.js,它负责监听URL或
<Route path="/f/:recordId" component={MyActionComponent}/>
import { connect } from 'react-redux';
import { replace } from 'react-router-redux';

const mapDispatchToProps = (dispatch: Dispatch) => ({
  visitNextLocation: () => dispatch(replace('/success')),
  myAction: (recordId) => dispatch(myAction(recordId)),
});

const withDispatch = connect(null, mapDispatchToProps);

class MyActionComponent extends Component {
  props: {
    match: {
      params: {
        recordId: string,
      }
    },
    redirectToLogin: () => void,
    myAction: string => void,
  };

  componentWillMount() {
    const recordId = this.props.match.params.recordId;
    if (recordId) {
      this.props.myAction(token);
      this.props.visitNextLocation();
    }
  }

  render() {
    return null;
  }
}
...
},
'/users': {
  component: dynamicWrapper(app, ['rule'], () => import('../routes/users')),
},
'/f/:userID': {
  component: dynamicWrapper(app, ['rule'], () => import('../routes/users')),
},
...
import React, { PureComponent } from 'react';
import { connect } from 'dva';
import { Row, Col, Card, List, Divider, Badge, Select, Radio, Input, Popover, Button, Table, Spin } from 'antd';
import RightPanel from './RightPanel';
import LeftPanel from './LeftPanel';
import { routerRedux, Route, Switch } from 'dva/router';
import 'font-awesome/css/font-awesome.min.css';
import FadeIn from 'react-fade-in';

@connect(({ rule, loading }) => ({rule, loading: loading.models.rule }))
export default class Users extends React.Component {
      constructor(props) {
        super(props)
        this.state = {
          selected_user: [],
          defaultView: true,
          isLoadingNow: false,
          selectedRowKeys: [],
          makeEmpty: false,
          searchRes: []
      }
    }

        selectRow = (record) => {       
            const { dispatch, match } = this.props;
            dispatch(routerRedux.replace({ pathname: '/f/' + record.id }));

            this.setState({isLoadingNow: true, selectedRowKeys: record.key})
            setTimeout(() => {
              this.setState({
                    isLoadingNow: false,
                    defaultView: false,
                    selected_user: record
                })
            }, 75)
        }

        componentDidMount() { 
            const { dispatch, match } = this.props;
            dispatch({
                type: 'rule/fetch'
            });
            if (match.params.userID == undefined) {
                // do nothing
            } else if (match.params.userID) {
                var result = this.props.rule.data.list.filter(function( obj ) {
                  return obj.id == match.params.userID;
                });
                this.selectRow.bind(this, result[0])
            }
        }

        render() {

            const { selectedRowKeys } = this.state;
            const rowSelection = {
                selectedRowKeys,
                type:"radio"
            };

            const { rule: { data }, loading } = this.props;

            return (<div>

                            <LeftPanel
                                rowSelection={rowSelection}
                                dataSource={this.state.makeEmpty ? this.state.searchRes : this.props.rule.data.list} 
                                selectRow={this.selectRow} 
                                loadingStatus={loading}
                            />
                          <RightPanel 
                                selected_user={this.state.selected_user}
                                is_default={this.state.defaultView}
                                loading={this.state.isLoadingNow}
                          />
                        </div>);


}
}
import React from 'react';
import { Table, Card } from 'antd';

import styles from './index.less';
// import 'font-awesome/css/font-awesome.min.css';

import { Row, Col, List, Divider, Badge, Select, Radio, Input, Popover, Button } from 'antd';

var moment = require('moment');

class LeftPanel extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            selected_row_index: undefined
        }
    }   
    handleChangeStyleOnSelectRow(index) {
        this.setState({
            selected_row_index: index
        }, console.log(this.state.selected_row_index))
    }

    prettifyForTable(raw_data) {
      var prettyRows = [];
      raw_data.map((item,index) =>
        prettyRows.push(
          <div style={{"width": "100%"}}> 
            <Row style={{  "align-items": "center"}} type="flex" justify="space-between">
                <Col span={10}>
                    <div style={{"font-size": "15px", "text-align": "center"}}>
                        {item.user_name} <i style={{"color": "rgba(0, 0, 0, 0.25)", "margin": "0 10px", "transform": "rotate(45deg)"}} className="fa fa-plane"> </i> {item.user_age}
                        <div style={{"font-size": "12px", "color": "grey"}}> {moment(item.user_color).format('HH:MM')} · {moment(item.user_order).format('HH:MM')}  </div>
                    </div>
                </Col>
                <Col span={3}>
                    <div style={{"text-align": "right", "text-align": "center"}}>
                      {item.user_family}
                    </div>
                </Col>
                <Col span={6}>
                    <div style={{"text-align": "right", "text-align": "center"}}>
                      {moment(item.user_height).format('MMMM D')}
                    </div>
                </Col>
                <Col span={3}>
                    <div style={{"text-align": "center"}}>
                        {(item.status == "in_progress") ? <div> <Badge style={{"padding-right": "25px"}} status="processing"/></div> : <div style={{"text-align": "center"}}> <Badge style={{"padding-right": "25px"}} status="default"/></div>}
                    </div>
                </Col>
            </Row>
          </div>
        )
      );
      return prettyRows;
    }


  render() {
    const stylesSelectedRow = { "background": "rgba(155,155,155,0.05)", "box-shadow": "0 0 5px 0 #4A90E2", "transform": "scale(1.01)"};
    const { dataSource } = this.props;
        return(
         <div>
            {dataSource &&
          <Card bordered={false} loading={this.props.loadingStatus} className={styles.userRows} bodyStyle={{"padding": "0 15px"}}>
                <List
                  size="small"
                  bordered={false}
                  dataSource={this.prettifyForTable(dataSource)}
                  renderItem={(item, index) => (<List.Item onClick={() => {this.state.selected_row_index == index ? null : this.props.selectRow(this.props.dataSource[index]); this.handleChangeStyleOnSelectRow(index)}} style={this.state.selected_row_index == index ? stylesSelectedRow : null} className={styles.userRows}>{item}</List.Item>)}
                />
          </Card>
            }
        </div>
    )
  }
}

export default LeftPanel;
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import infopng from '../../../assets/info.svg';

import TabInformations from './TabInformations.js';
import TabFamily from './TabFamily.js';
import TabProblems from './TabProblems.js';
import { Tabs, Button, Spin, Icon, Table, Pagination, Card, Col, Row, Spinner, Badge } from 'antd';
const TabPane = Tabs.TabPane;
import 'font-awesome/css/font-awesome.min.css';
import WindowSizeListener from 'react-window-size-listener'
import FadeIn from 'react-fade-in';

export default class RightPanel extends Component {

  render() {

    if (this.props.loading) {
        return(
            <div> 
          <Spin 
            indicator={<Icon type="loading" style={{ fontSize: 24 }} spin />}
                    src="http://web.gndu.ac.in/DepartmentProfile/images/spinner.gif"
                />
            </div>
        );
    } else if (this.props.is_default) {
      return(
          <div style={{"margin-top": "64px", "margin-right": "10px", "text-align": "center", "height": "90vh", "display": "flex", "align-items": "center", "justify-content": "center"}}> 
            <div>
                <img src={infopng} style={{"height": "155px"}} />
                <p style={{"color": "#8e8e8e"}}> select a user on the <br/> left-hand side... </p>
               </div>
          </div>
        );
    } else {
    return (

      <FadeIn>

      <Card bodyStyle={{"padding": "0"}} style={{"background-color": "white", "height":"90vh", "padding": "20px", "box-shadow": "rgba(0, 21, 41, 0.1) 0px 0px 6px", "opacity": "1", "transition": "background 0.6s", "border-radius": "2px", "margin": "10px 10px 0 0px", "margin-top": "64px"}}> 
            <Tabs defaultActiveKey="1" style={{"text-align": "center", "padding": "0 15px"}}>
        <TabPane tab="General" key="1">
          <TabInformations
                    selected_user={this.props.selected_user}
                />
            </TabPane>
            <TabPane tab="Servicing" key="2">
          <TabFamily 
            selected_user={this.props.selected_user} 
          />
          </TabPane>
          <TabPane tab={<div>Defect(s)<Badge showZero count={0} style={{ backgroundColor: '#fff', color: '#999', boxShadow: '0 0 0 1px #d9d9d9 inset', "margin-left": "10px" }} /></div>} key="3">
          <TabProblems />
        </TabPane>
        </Tabs>
    </Card>
    </FadeIn>
    );
  }
}
}