[React+Rails] 타이핑 효과나는 텍스트 제작하기
현재 프로젝트에 속보를 알려주는 타이핑 효과가 나는 텍스트를 리액트 컴포넌트로 바꿔보려 합니다.
구글링을 해보니, 리액트 타이핑 효과를 내는 모듈이 많습니다. 그 중 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이 변경될때마다) 타이핑을 시작합니다!