Reactでセル内で自動改行と文字コードによる改行を両立させる方法
こんにちは、joniyです。
もうすぐ春アニメも終わってしまいますね。
今期で乗りに乗っていて常におもしろかったのは「この素晴らしい世界に祝福を!」でしょうか。
2期も決定してもう言うこと無いですね。ありがとうございます!!!!!!
はい、本題に入ります。
問題
2016/03/16ぐらいから、Reactをフロントで使っているプロジェクトで
セルから文字がはみ出るようになりました。
元々の実装(一部)
| ... 1 | var innerValue = this.props.value; 2 | if this.props.multiLine 3 | innerValue = <pre>{innerValue}</pre> 4 | render() { 5 | <td>{innerValue}</td> 6 | } | ...
このようにpreタグを付けることでセル内で改行コードによる改行を実装していました。
これでも、問題なく意図した表示がされていたと思うのですが、
ブラウザ(Chrome)のpreタグの優先度が上がったのかもしれません。
表示結果
結論
改行コード毎に別コンポーネントを呼び出して、
呼び出し先コンポーネントで末尾に<br />
を付けることで解決しました。
呼び出し元コンポーネントの一部
| ... 1 | var multiLineCells = []; 2 | var splitValues = innerValue.split('\n'); 3 | for (index in splitValues) { 4 | eachLine = splitValues[index]; 5 | multiLineCells.push(<MultiLineCell key={key} eachValue={eachLine} />); 6 | innerValue = multiLineCells; 7 | render() { 8 | <td>{innerValue}</td> 9 | } | ...
呼び出し先コンポーネント
1 |class MultiLineCell extends React.Component { 2 | constructor(props) { 3 | super(props); 4 | } 5 | 6 | render() { 7 | return ( 8 | <div>{this.props.eachValue}<br /></div> 9 | ); 10 | } 11 |} 12 | 13 |MultiLineCell.PropTypes = { 14 | eachValue: React.PropTypes.string.isRequired 15 |}; 16 |window.MultiLineCell = MultiLineCell
解決策の模索経緯
preタグを消してみる
単純にpreタグを消してみました。
改行コードで改行してくれなくなりました。まあそうですよね(´・ω・`)
表示結果
CSSで指定してみる
word-wrap
、white-space
、word-break
を試してみましたが、
どれもセル内で自動改行と文字コードによる改行を両立できませんでした。
\nを<br>に置き換えてみる
brタグをhtmlタグと認識してくれなかったのでアウト。
表示結果
改行コード毎に別コンポーネントを呼び出す
最終的にこの方法で解決しました。
表示結果
終わりに
ちょっとゴリ押しで解決してしまったのでは?と思いますが、
元コードの変更箇所も少ないので悪くない解決方法だと思います。
新しいコンポーネントを作成するついでにES6で書いてみました。
最近ずっとCoffeeScriptに慣れていたのでセミコロンが新鮮でした。
ちなみに、CoffeeScriptとES6をこのReactプロジェクトでは共存させています。
方法はいるかさんさんが記事にまとめてくれているので興味のある方はご参照ください!
RailsでCoffeeScriptを共存させつつES6やJSXを使う方法
オチ
いるかさんさん:今、適当なページでテーブルタグで再現させて、CSSだけで解決できたよー
いるかさんさん:white-space: pre-wrap
したら折り返された。
joniy:えっ....
確認してみた。
| ... 1 | var innerValue = this.props.value; 2 | var style = []; 3 | if this.props.multiLine 4 | style['white-space'] = 'pre-wrap' 5 | render() { 6 | <td style={style}>{innerValue}</td> 7 | } | ...
表示結果
...。
CSS調べたつもりでしたが確認不足でした...。
最後に一言。
この素晴らしい世界にpre-wrapを!!!!!