옛글/Frontend

[React+Rails] 타이핑 효과나는 텍스트 제작하기

ShakeJ 2019. 3. 26. 16:11


현재 프로젝트에 속보를 알려주는 타이핑 효과가 나는 텍스트를 리액트 컴포넌트로 바꿔보려 합니다. 


구글링을 해보니, 리액트 타이핑 효과를 내는 모듈이 많습니다. 그 중 react-typist 라는 패키지를 사용해보겠습니다. 

(Typist로만 감싸주면 애니메이션 효과가 나타나는 것이 간단해보여서 선택해봅니다)


1
npm install react-typist --save
cs


npm을 통해 설치합니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
       <div class="ticker">
          <ul>
             <% breakings = Article.order("created_at desc").limit(10) %>
             <% breakings.each do |article| %>
              <li>
                <a href="/API주소?파라미터=<%= article.id %>" target="_blank">
                  <strong>속보</strong>
                  <% title = article.title %>
                  <% if title.length > 100 %>
                    <% title = "#{title[0..100]}..." %>
                  <% end %>
                  <%= title %>
                </a>
              </li>
             <% end %>
         </ul>
        </div>
cs


Rails view에서 직접 쿼리를 날려 받아와 작성 된 코드입니다. (지저분..)


해당 코드 외에도 typed.js를 초기화하는 자바스크립트가 존재합니다. 


전부 삭제! 하고 

1
<%= react_component("BreakingNewsType") %>
cs


컴포넌트 호출 단을 HTML에 추가합니다. 


app/javascript/components/BreakingNewsType.js 파일을 생성합니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React, {Component} from 'react';
import Typist from 'react-typist';
 
export default class BreakingNewsType extends Component {
 
  render() {
    return (
      <Typist>
        Animate this text.
      </Typist>
    );
  }
}
 
cs


오호 export default를 하단에 적어줄 수도 있지만, 클래스 앞쪽에 통합해서 적을 수 있네요. 


이렇게 예제를 적고 웹을 보니, 



정상적으로 타이핑 애니메이션이 동작합니다.


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
import React, {Component} from 'react';
import Typist from 'react-typist';
 
const API = '';
 
export default class BreakingNewsType extends Component {
  constructor(props) {
    super(props);
    this.state = {
      title: []
    };
  }
 
  componentDidMount() {
    this.intervalId = setInterval(() => this.loadData(), 1000 * 5);
    this.loadData();
  }
 
  componentWillUnmount() {
    clearInterval(this.intervalId);
  }
 
  loadData() {
    console.log("load breaking news");
    fetch(API)
      .then(response => response.json())
      .then(data => this.setState({
        title: data.title
      }));
  }
 
  render() {
    return (
      <div className="ticker_container">
        <Typist>
          <b>최신</b> {this.state.title}
        </Typist>
      </div>
    );
  }
}
cs


API를 만들고, 받아온 최신 뉴스를 보여주도록 만들었습니다. 


어랏 근데 동작을 안합니다.


loadData() 이후 데이터를 받고 나면 타이핑을 시작해주어야 하는 듯 합니다. 


state가 바뀌는데 왜 다시 render를 하지 않을까? 혹시 restart라는 함수가 있거나, update?를 호출해주어야 하나 싶어 살펴봅니다. (아니야 이러면 react의 장점이 없잖아!)

분명 react는 state가 변경되면, 자동으로 뷰가 변경될텐데... 싶어 찾다보니, react-typist에 key라는 것을 발견합니다. 


key의 경우 여러가지 문장을 이어서 쓰려고 할 때, 설정을 하는 것이라고 합니다. 

key는 고유값이니, api를 통해 받아온 뉴스의 ID값(고유값)으로 추가해 봅니다. 


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
export default class BreakingNewsType extends Component {
  constructor(props) {
    super(props);
    this.state = {
      title: [],
      textIndex: 0,
    };
  }
 
  componentDidMount() {
    this.intervalId = setInterval(() => this.loadData(), 1000 * 5);
    this.loadData();
  }
 
  componentWillUnmount() {
    clearInterval(this.intervalId);
  }
 
  loadData() {
    fetch(API)
      .then(response => response.json())
      .then(data => this.setState({
        title: data.title,
        textIndex: data.id,
      }));
    this.forceUpdate();
  }
 
  render() {
    return <div key={this.state.textIndex} className="ticker_container">
        <Typist>
          <b>최신</b> {this.state.title}
        </Typist>
      </div>
  }
}
 
cs


오.. key가 변경될때마다 (state 내에 title이 변경될때마다) 타이핑을 시작합니다!