В настоящее время я создаю с помощью React шаблон входа / регистрации, который по функциональности имитирует groupon логин. В частности, я нацелен на переключение цветной границы при переключении между i have an account и i'm a new customer. Шаблон очень распространен в сегодняшней разработке, и я видел много плохо написанных решений, которые полностью игнорируют лучшие практики.
Начну с утверждения, что лучшее решение использует state.
Затем я бы создал следующее (очевидно, неполное):
<div className = "wrapper">
<div className = "login" />
<div className = "register" />
</div>
Затем я подумал дать обоим divs состояние и спецификацию border-bottom для рендеринга цветной границы. Проблема, которую я вижу, заключается в том, как лучше всего реализовать переключение того, какой из них активен.
Другой мысленный эксперимент - жестко закодировать все, вплоть до полей ввода. Затем, когда пользователь нажимает на поле I'M A NEW CUSTOMER, все, что мне нужно сделать, это установить активное состояние для этого компонента и выполнить рендеринг.
Опять же, суть этого вопроса состоит в том, чтобы ответить, как лучше всего реализовать эту форму входа / регистрации. Кстати, Groupon присваивает их показывающему компоненту класс active.
РЕДАКТИРОВАТЬ: Как было указано Санни Вонгом и отражает мое предположение, его решение использует состояние и реализует с моим компонентом следующим образом:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
activeTab: "login"
};
}
handleActiveTab = name => event => {
this.setState({ activeTab: name });
};
render() {
const { activeTab } = this.state;
let joinComponent =
activeTab === "login" ? <LoginComponent /> : <RegisterComponent />;
return (
<div className = "wrapper">
<div
onClick = {this.handleActiveTab("login")}
className = {classNames("login", {
active: activeTab === "login"
})}
>
Login
</div>
<div
onClick = {this.handleActiveTab("register")}
className = {classNames("register", {
active: activeTab === "register"
})}
>
Register
</div>
{joinComponent}
</div>
);
}
}
Кроме того, сообщение было помечено как too broad, но я ориентировался на конкретные темы / вопросы. Подводя итог, они были:
Specifically, I am targeting the switching of the colored border when toggling between i have an account and i'm a new customer.
answer how to best implement this login/registration form
Дополнительную информацию см. В живая версия.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


<div className = "wrapper">
<div className = {`login ${this.state.active==CONST.LOGIN? 'active':''}`} onClick = {e=>{this.setState({active:CONST.LOGIN}}/>
<div className = {`register ${this.state.active==CONST.REGISTER? 'active':''}`} onClick = {e=>{this.setState({active:CONST.REGISTER}} />
</div>
вы должны поддерживать состояние active в активном, что позволит вам загрузить правильный компонент (войти / зарегистрироваться). CONST.LOGIN и CONST.REGISTER - это константы, которыми вы должны управлять. вы можете использовать только половину грязного способа.
Переключение классов - это лучший вариант. Нет необходимости повторно отображать вкладки как разные компоненты, так как содержимое одинаковое. Вкладки претерпевают только косметические изменения. Существует библиотека под названием classNames (https://www.npmjs.com/package/classnames), которая чрезвычайно помогает контролировать, какие классы применяются в данной ситуации.
Что-то вроде сохранения состояния того, какая ссылка активна, через идентификатор. Затем переключите «активный» класс, который отвечает за применение активного стиля.
state = { activeTab: 'login' }
handleActiveTab = e => {
//sets state of activeTab
}
render() {
const { activeTab } = this.state;
return (
<div className = "wrapper">
<div onClick = {this.handleActiveTab} className = {classNames('login', { active: activeTab === 'login' })} />
<div onClick = {this.handleActiveTab} className = {classNames('register', { active: activeTab === 'register' })} />
</div>
);
}
Потому что вы вызываете функцию в обработчике onClick при рендеринге компонента. Функция также вызывает setState, который вызывает рендеринг, который снова вызывает функцию. Вы сделали все правильно, чтобы предотвратить бесконечный цикл, но ввели то, что считается анти-шаблоном, поскольку эта вторая функция анонимна. Каждый раз при повторном рендеринге вы будете создавать новую функцию, на которую в response нет ссылки. Я уверен, что вы можете найти ресурсы в поисковой системе «реагировать-антипаттерны». Я не считаю, что это узкое место, если вы не используете этот компонент для рендеринга сотен вкладок.
Это было здорово, спасибо за ответ. Я отредактировал оригинал, чтобы отразить мою реализацию. У меня есть один вопрос: если я не укажу
handleActiveTab = name => event => {}с двойной функцией, я получу бесконечный цикл (см.handleActiveTab = name => {}). Есть идеи, почему?