Kselax.ru

Hacker Kselax — the best hacker in the world

Menu
  • Блог
  • Контакты
  • wp plugin генератор
  • Русский
    • Русский
    • English
Menu

Как использовать react-router для нескольких языков

Posted on 13 мая, 201913 мая, 2019 by admin

Это часто нужно создать сайт что будет поддерживать несколько языков, для примера я собираюсь создать мультиязычный сайт который будет поддерживать 3 языка пока что. Потом я добавлю еще несколько.

И так, я хочуу создать с тремя ua, ru и en. И в этой статье я объясну вам как это реализовать.

Как react-router работает с мультиязычными сайтами

Короткое описание и понимание что мы делаем. Наш сайт будет иметь ссылки:

site.com — it will redirect to site.com/[locale]/

site.com — это будет редиреткить на site.com/[locale]/

site.com/en/ — English версия
site.com/ru/ — Russian версия
site.com/ua/ — Ukrainian версия

site.com должен редиректить пользователей на en или ru или ua

он редиректит на ru если locale в window.localStorage.getItem(‘locale’). Если это не инициализировано он будет инициализировано в ‘en‘ window.localStorage.setItem(‘locale’, ‘en’)

все остальные урлы такие как site.com/de/, site.com/sdf/, site.com/adfsdf… etc. будут редиректить на 404 page.

когда урлы начинаются с site.com/ru/ etc. и locale установлена в en то это будет локаль из урл и изменение сохраненной локали в url локаль.

И так начинаем!

Мы должны установить react-router-dom 

1
npm i react-router-dom

 

и потом импортировать компоненты

1
2
3
4
5
6
import { BrowserRouter as Router,
         Route,
         Link,
         Redirect,
         Switch,
         withRouter } from 'react-router-dom'

Теперь создаем 4 компонента

Home, About, Contacts и NoFound для 404 error

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const Home = (props) => {
  return <div>
    <LangButtons {...props} />
    <h1>Home</h1>
  </div>
}
 
const About = (props) => {
  return <div>
    <LangButtons {...props} />
    <h1>About</h1>
  </div>
}
 
const Contacts = (props) => {
  return <div>
    <LangButtons {...props} />
    <h1>Contacts</h1>
  </div>
}
 
const NoFound = (props) => {
  return <div>
    <LangButtons {...props} />
    <h1>404</h1>
  </div>
}

<LangButtons> это компонент что рендерит три кнопки en, ru, ua, которые будут изменять язык.

потом мы создаем <LangRouter> где помещаем 3 роута для каждого языка с регулянрыми выражениями /en/* /ru/* и /ua/*.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class LangRouter extends React.Component {
  constructor(props) {
    super(props)
 
    let locale = window.localStorage.getItem('locale')
    if (locale === null) {
      window.localStorage.setItem('locale', 'en')
      locale = 'ru'
    }
    this.state = {
      locale: locale
    }
  }
 
  setLocale = (newLocale) => {
    console.log('newLocale = ', newLocale);
    window.localStorage.setItem('locale', newLocale)
    this.setState({ locale: newLocale })
  }
 
  render() {
    const { locale } = this.state
    return (
      <Switch>
        <Route path="/" exact render={propRouter => {
          return <Redirect to={locale + "/"} />
        }} />
        <Route path="/en/*" render={
          propsRouter =>
            <App
              {...propsRouter}
              locale={locale}
              setLocale={this.setLocale}
            />
        }/>
        <Route path="/ru/*" render={
          propsRouter =>
            <App
              {...propsRouter}
              locale={locale}
              setLocale={this.setLocale}
            />
        } />
        <Route path="/ua/*" render={
          propsRouter =>
            <App
              {...propsRouter}
              locale={locale}
              setLocale={this.setLocale}
            />
        } />
        <Route path="*" render={
          propsRouter =>
            <NoFound
              {...propsRouter}
              locale={locale}
              setLocale={this.setLocale}
            />
        } />
      </Switch>
    )
  }
}

Это корневой компонет в котором сохранена locale нашего приложения для всех child компонент. В конструкторе мы проверяем window.localStorage на ‘local’ и если это установлено то мы инициализируем this.state.locale с этим значением и передаем вниз компонентам. Функция setLocal используется передавать вниз как это называется two way binding. Эта функция будет передваваться кнопкам которые будут изменять this.state.locale.

в Route мы используем render потому что мы должны  передать  setLocal и this.state.locale к children, и так мы не можем использовать component.

Теперь, давайте создадим App

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const App = (props) => {
  let { locale } = props
  let urlLocale = props.location.pathname.substring(1, 3)
  if ( locale !== urlLocale ) {
    props.setLocale(urlLocale)
    locale = urlLocale
  }
  return (
    <div>
      <Link to={"/" + locale + "/"}>Home</Link> |{' '}
      <Link to={"/" + locale + "/about"}>About</Link> |{' '}
      <Link to={"/" + locale + "/contacts"}>Contacts</Link>
      <Switch>
        <Route path={"/" + locale + "/"} exact render={propRouter =>
          <Home {...propRouter} {...props} />
        } />
        <Route path={"/" + locale + "/about"} render={propRouter =>
          <About {...propRouter} {...props} />
        } />
        <Route path={"/" + locale + "/contacts"} render={propRouter =>
          <Contacts {...propRouter} {...props} />
        } />
        <Route path="*" render={propRouter =>
          <NoFound {...propRouter} {...props} />
        } />
      </Switch>
    </div>
  )
}

Он принимает props и проверяет locale из url если они разные, урл значение будет установлено locale из родительского компонента вызовом function props.setLocale(urlLocale)

Потом мы видим несколько <Link> елементов и <Route> где динамически генерируются пути. Снова мы используем render потому что мы должны передавать данные к children.

 

Последний елемент LangButtons.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class LangButtons extends React.Component {
  setLocale = (newLocale) => {
    const { locale } = this.props
    let url = '/' + newLocale + this.props.location.pathname.substring(3)
    this.props.history.push(url)
    this.props.setLocale(newLocale)
  }
 
  render() {
    return (
      <div>
        <button
          onClick={() => this.setLocale('ru')}
        >ru</button> | <button
          onClick={() => this.setLocale('en')}
        >en</button> | <button
          onClick={() => this.setLocale('ua')}
        >ua</button>
      </div>
    )
  }
}

Каждая кнопка имеет свой собственные обработчик событий которые вызывает props function setLocale и изменяет locale

Ниже весь код

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router,
         Route,
         Link,
         Redirect,
         Switch,
         withRouter } from 'react-router-dom'
 
class LangButtons extends React.Component {
  setLocale = (newLocale) => {
    const { locale } = this.props
    let url = '/' + newLocale + this.props.location.pathname.substring(3)
    this.props.history.push(url)
    this.props.setLocale(newLocale)
  }
 
  render() {
    return (
      <div>
        <button
          onClick={() => this.setLocale('ru')}
        >ru</button> | <button
          onClick={() => this.setLocale('en')}
        >en</button> | <button
          onClick={() => this.setLocale('ua')}
        >ua</button>
      </div>
    )
  }
}
 
const Home = (props) => {
  return <div>
    <LangButtons {...props} />
    <h1>Home</h1>
  </div>
}
 
const About = (props) => {
  return <div>
    <LangButtons {...props} />
    <h1>About</h1>
  </div>
}
 
const Contacts = (props) => {
  return <div>
    <LangButtons {...props} />
    <h1>Contacts</h1>
  </div>
}
 
const NoFound = (props) => {
  return <div>
    <LangButtons {...props} />
    <h1>404</h1>
  </div>
}
 
 
 
const App = (props) => {
  let { locale } = props
  let urlLocale = props.location.pathname.substring(1, 3)
  if ( locale !== urlLocale ) {
    props.setLocale(urlLocale)
    locale = urlLocale
  }
  return (
    <div>
      <Link to={"/" + locale + "/"}>Home</Link> |{' '}
      <Link to={"/" + locale + "/about"}>About</Link> |{' '}
      <Link to={"/" + locale + "/contacts"}>Contacts</Link>
      <Switch>
        <Route path={"/" + locale + "/"} exact render={propRouter =>
          <Home {...propRouter} {...props} />
        } />
        <Route path={"/" + locale + "/about"} render={propRouter =>
          <About {...propRouter} {...props} />
        } />
        <Route path={"/" + locale + "/contacts"} render={propRouter =>
          <Contacts {...propRouter} {...props} />
        } />
        <Route path="*" render={propRouter =>
          <NoFound {...propRouter} {...props} />
        } />
      </Switch>
    </div>
  )
}
 
 
 
class LangRouter extends React.Component {
  constructor(props) {
    super(props)
 
    let locale = window.localStorage.getItem('locale')
    if (locale === null) {
      window.localStorage.setItem('locale', 'en')
      locale = 'ru'
    }
    this.state = {
      locale: locale
    }
  }
 
  setLocale = (newLocale) => {
    console.log('newLocale = ', newLocale);
    window.localStorage.setItem('locale', newLocale)
    this.setState({ locale: newLocale })
  }
 
  render() {
    const { locale } = this.state
    return (
      <Switch>
        <Route path="/" exact render={propRouter => {
          return <Redirect to={locale + "/"} />
        }} />
        <Route path="/en/*" render={
          propsRouter =>
            <App
              {...propsRouter}
              locale={locale}
              setLocale={this.setLocale}
            />
        }/>
        <Route path="/ru/*" render={
          propsRouter =>
            <App
              {...propsRouter}
              locale={locale}
              setLocale={this.setLocale}
            />
        } />
        <Route path="/ua/*" render={
          propsRouter =>
            <App
              {...propsRouter}
              locale={locale}
              setLocale={this.setLocale}
            />
        } />
        <Route path="*" render={
          propsRouter =>
            <NoFound
              {...propsRouter}
              locale={locale}
              setLocale={this.setLocale}
            />
        } />
      </Switch>
    )
  }
}
 
ReactDOM.render(
  <Router>
    <LangRouter />
  </Router>,
  document.getElementById('root')
)

 

Мы получили следующий результат.

 

Добавить комментарий Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Рубрики

  • C++ (293)
  • JavaScript (1)
  • linux (1)
  • MFC (39)
  • node.js (2)
  • React (3)
  • uncategorized (1)
  • vBulletin (5)
  • Visual Studio (9)
  • wordpress (18)
  • Разное (29)

Метки

Ajax bootstrap CentOS CLI expressjs FormData GDlib google Invisible reCAPTCHA JWT media MFC php react-router-dom redux repository wordpress RTTI STL vBulletin vector Visual Studio WINAPI wordpress wp-plugins XMLHttpRequest Двоичное дерево Задачи С++ Игры С++ Исключения С++ О-большое Операторы_С++ Перегрузка операторов С++ Поиск С++ Потоки Проектирование_С++ С++ Типы_С++ Типы С++ Шаблоны С++ библиотеки локализация макросы С++ сортировка С++

Свежие комментарии

  • RA3PKJ к записи visual C++, создание диалоговых окон.
  • JasonReant к записи Создание и использование статических библиотек .lib в visual studio.
  • MyWin2020 к записи Программка для заполнения форума на vBulletin 3.8.7
  • ScottJip к записи Создание и использование статических библиотек .lib в visual studio.
  • ArnoldKig к записи Создание и использование статических библиотек .lib в visual studio.
©2021 Kselax.ru Theme by ThemeGiant