使用react-router-dom在同一页面上进行不需要的渲染

时间:2018-09-12 07:39:36

标签: javascript reactjs meteor react-router-v4

我目前正在使用React-router-dom(React路由器4),我希望为客户提供详细信息页面。我可以成功获取所有数据,但是数据与列表/概述显示在同一页面上。图片将使事情变得清晰。我想有两个不同的观点。

unwanted rendering on same page

这是路由器的结构:

const unauthenticatedPages = [
  '/',
  '/login'
];
const authenticatedPages = [
  '/admin'
];

// public pages
const publicPage = () => {
  if(Meteor.userId()) {
    history.push('/');
  }
};

// private pages
const privatePage = () => {
  if(Meteor.userId()) {
    history.push('/');
  }
};

// check authentication for pages
export const onAuthenticationChange = (authenticated) => {
  console.log('is authenticated...', authenticated);

  const path = this.location.pathname;
  const isUnauthenticatedPage = unauthenticatedPages.includes(path);
  const isAuthenticatedPage = authenticatedPages.includes(path);

  if( authenticated && isUnauthenticatedPage ) {
    console.log('Can view the page routed to the path dashboard');
  } else if (!authenticated && isAuthenticatedPage) {
    console.log('No rights to view the page... routed to the path 
    login page');
  }
}

// render app inside custom templates
const RouteWithLayout = ({layout, component, ...rest}) => {
  return (
   <Route {...rest} render={ (props) => React.createElement( layout, props, React.createElement(component, props)) } />
  );
};

export const routes = (
  <BrowserRouter>
    <Switch>
        <RouteWithLayout exact path="/" layout={AuthenticationLayout} onEnter={publicPage} component={AuthLogin} />
        <RouteWithLayout path="/login" layout={AuthenticationLayout} onEnter={publicPage} component={AuthLogin} />

        <AdminLayout>
            <Route path="/admin" component={AdminDashboard} />
            <Route path="/klanten/:customerID" component= . {CustomerDetails} />
            <Route path="/klanten" component={CustomerOverview} />

            <Route path="/nieuwe-klant" component={CustomerCreate} />
        </AdminLayout>

        <Route path="*" component={PageNotFound} />
    </Switch>
</BrowserRouter>
);

其他信息: 我对此路由器还有其他问题。我使用了alanning:roles,因为用户必须根据其角色扮演路由器。该图像显示了管理区域,但是用户将使用具有较少选项的类似布局。我该如何实现?

如果我使用/ new-customer /之类的单独路由,我会看到一个仅包含表单的新页面,但是我想使用/ customer / new /作为路由。如果我将路由更改为/ customer / new /,则不会显示我的页面。

/ new-customer /页面的代码:

class CustomerCreate extends Component {
  constructor(props) {
    super(props);
    this.state = {
        message: ''
    };
  }
  onFormSubmit(event) {
    event.preventDefault();

    const relationNumber                = this.refs.relationNumber.value;
    const companyName                   = this.refs.companyName.value;
    const locationStreet                = this.refs.locationStreet.value;
    const locationPostal                = this.refs.locationPostal.value;
    const locationCity                  = this.refs.locationCity.value;
    const contactPersonName         = this.refs.contactPersonName.value;
    const contactPersonEmail        = this.refs.contactPersonEmail.value;
    const contactPersonPhone        = this.refs.contactPersonPhone.value;
    const password                          = this.refs.password.value;
    const confirmPassword           = this.refs.confirmPassword.value;

    const checkEmail = (email) => {
    const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        const validated = regex.test(email);
        return validated;
    };

    const checkPassword = ( pwd, pwd2 ) => {
        if( pwd != '' || pwd2 != '' ){
            if ( pwd.length >= 5 ) { 
                if ( pwd === pwd2 ) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
    };

    const validatedEmail = checkEmail( contactPersonEmail );
    const validatedPassword = checkPassword( password, confirmPassword 
 ); 

    if(!validatedEmail) {
        this.setState({message: 'Het e-mailadres is niet correct.'});
    }
    if(!validatedPassword ) {
        this.setState({message: 'De wachtwoorden komen niet overeen!'});
    }

    if( validatedEmail && validatedPassword ) {
        try {
            const createdAccount = Accounts.createUser({
                email                       : contactPersonEmail,
                password                : password,
                relationNumber  : relationNumber,
                companyName         : companyName ,
                locationStreet  : locationStreet,
                locationPostal  : locationPostal,
                locationCity        : locationCity,
                contactName         : contactPersonName,
                contactPhone        : contactPersonPhone,
                isArchived          : 0,
                setRoles                : ['customer']
            });

            this.setState({message: 'De klant is succesvol toegevoegd!'});

            // send flashmessage of succesfull state

            return createdAccount;
        } catch( err ) {
            return err.reason;
        }
    }
    return false;
}

render() {
    return (
        <div>
         form sitting here ...
        </div>
    );
}
}
export default CustomerCreate;

3 个答案:

答案 0 :(得分:1)

Switch组件仅呈现单个立即子级。由于您的/klanten/klanten/:customerID路线不是组件的直接子级,因此只要路线与/klanten*匹配,它们都将呈现

您可以在exact路由上使用/klanten属性,以使其与/klanten/:customerID路由不匹配。

<Route path="/klanten/:customerID" component= . {CustomerDetails} />
<Route path="/klanten" exact component={CustomerOverview} />

答案 1 :(得分:0)

这是因为两条路由都匹配klanten。尝试将客户详细信息路径重命名为kunde。或者,正如其他人所建议的那样,将exact属性添加到klanten概述路径中。

要回答问题2,请在交换机中将customer/new放在customer/:id之前。并确保客户永远不能拥有“ new”的ID。

答案 2 :(得分:0)

现在,首先渲染React-Router:

    <Route path="/klanten/:customerID" component= . {CustomerDetails} />

然后:

    <Route path="/klanten" component={CustomerOverview} />

当您转到包含/ klanten的任何路径时。

重命名两条路由之一,或按如下所示添加精确值= {true}:

    <Route path="/klanten/:customerID" component= . {CustomerDetails} exact={true} />