>source

답을 검색했지만 찾을 수 없으므로 여기에서 묻습니다. 컨텍스트를 업데이트하는 소비자가 있습니다. 컨텍스트를 표시해야하는 다른 소비자. typescript (16.3)로 반응을 사용하고 있습니다.

컨텍스트 (AppContext.tsx) :

export interface AppContext {
    jsonTransactions: WithdrawTransactionsElement | null;
    setJsonTran(jsonTransactions: WithdrawTransactionsElement | null): void;
}
export const appContextInitialState : AppContext = {
    jsonTransactions: null,
    setJsonTran : (data: WithdrawTransactionsElement) => {
        return appContextInitialState.jsonTransactions = data;
    }
};
export const AppContext = React.createContext(appContextInitialState);

제작자 (App.tsx) :

interface Props {}
class App extends React.Component<Props, AppContext> {
  state: AppContext = appContextInitialState;
  constructor(props : Props) {
    super(props);
  }
  render() {
    return (
        <AppContext.Provider value={this.state}>
          <div className="App">
            <header className="App-header">
              <SubmitTransactionFile/>
              <WithdrawTransactionsTable />
            </header>
          </div>
        </AppContext.Provider>
    );
  }
}
export default App;

업데이트 컨텍스트 소비자 (SubmitTransactionFile.tsx)

class SubmitTransactionFile extends React.Component {
    private fileLoadedEvent(file: React.ChangeEvent<HTMLInputElement>, context: AppContext): void{
        let files = file.target.files;
        let reader = new FileReader();
        if (files && files[0]) {
            reader.readAsText(files[0]);
            reader.onload = (json) =>  {
                if (json && json.target) {
                    // @ts-ignore -> this is because result field is not recognized by typescript compiler
                    context.setJsonTran(JSON.parse(json.target.result))
                }
            }
        }
    }
    render() {
        return (
            <AppContext.Consumer>
                { context  =>
                    <div className="SubmitTransactionFile">
                        <label>Select Transaction File</label><br />
                        <input type="file" id="file" onChange={(file) =>
                            this.fileLoadedEvent(file, context)} />
                        <p>{context.jsonTransactions}</p>
                    </div>
                }
            </AppContext.Consumer>
        )
    }
}

export default SubmitTransactionFile;

디스플레이 소비자 (WithdrawTransactionsTable.tsx)를 마무리합니다 :

class WithdrawTransactionsTable extends React.Component {
    render() {
        return (
            <AppContext.Consumer>
                { context  =>
                    <div>
                        <label>{context.jsonTransactions}</label>
                    </div>
                }
            </AppContext.Consumer>
        )
    }
}
export default WithdrawTransactionsTable;

fileLoadedEvent 이후  함수는 context.setJsonTran 라고합니다  다른 소비자와 WithdrawTransactionsTable 를 다시 렌더링해야합니다.  구성 요소를 다시 렌더링해야하지만 그렇지 않습니다.

내가 잘못한 것은 무엇입니까?


  • 답변 # 1

    상태를 업데이트 할 때 제공자의 다시 렌더링을 트리거하지 않으므로 소비자 데이터가 변경되지 않습니다. setState를 사용하여 상태를 업데이트하고 다음과 같이 공급자에게 컨텍스트 값을 할당해야합니다.

    class App extends React.Component<Props, AppContext> {
      constructor(props : Props) {
        super(props);
        this.state = {
             jsonTransactions: null,
             setJsonTran: this.setJsonTran
        };
      }
      setJsonTran : (data: WithdrawTransactionsElement) => {
            this.setState({
                 jsonTransactions: data
            });
      }
      render() {
        return (
            <AppContext.Provider value={this.state}>
              <div className="App">
                <header className="App-header">
                  <SubmitTransactionFile/>
                  <WithdrawTransactionsTable />
                </header>
              </div>
            </AppContext.Provider>
        );
      }
    }
    export default App;
    
    

  • 답변 # 2

    귀하의 setJsonTran   value 를 발생시키지 않는 컨텍스트의 기본값을 변경합니다.   Provider 에 주어진  바꾸다.

    대신 jsonTransactions 를 유지할 수 있습니다  최상위 상태 에서이 상태를 변경하고 value 를 업데이트하는 함수를 전달하십시오. .

    const AppContext = React.createContext();
    class App extends React.Component {
      state = {
        jsonTransactions: null
      };
      setJsonTran = data => {
        this.setState({ jsonTransactions: data });
      };
      render() {
        const context = this.state;
        context.setJsonTran = this.setJsonTran;
        return (
          <AppContext.Provider value={context}>
            <div className="App">
              <header className="App-header">
                <SubmitTransactionFile />
                <WithdrawTransactionsTable />
              </header>
            </div>
          </AppContext.Provider>
        );
      }
    }
    
    

    const AppContext = React.createContext();
    class App extends React.Component {
      state = {
        jsonTransactions: null
      };
      setJsonTran = data => {
        this.setState({ jsonTransactions: data });
      };
      render() {
        const context = this.state;
        context.setJsonTran = this.setJsonTran;
        return (
          <AppContext.Provider value={context}>
            <div className="App">
              <header className="App-header">
                <SubmitTransactionFile />
                <WithdrawTransactionsTable />
              </header>
            </div>
          </AppContext.Provider>
        );
      }
    }
    class SubmitTransactionFile extends React.Component {
      fileLoadedEvent(file, context) {
        let files = file.target.files;
        let reader = new FileReader();
        if (files && files[0]) {
          reader.readAsText(files[0]);
          reader.onload = json => {
            if (json && json.target) {
              // slice just to not output too much in this example
              context.setJsonTran(json.target.result.slice(0, 10));
            }
          };
        }
      }
      render() {
        return (
          <AppContext.Consumer>
            {context => (
              <div className="SubmitTransactionFile">
                <label>Select Transaction File</label>
                <br />
                <input
                  type="file"
                  id="file"
                  onChange={file => this.fileLoadedEvent(file, context)}
                />
                <p>{context.jsonTransactions}</p>
              </div>
            )}
          </AppContext.Consumer>
        );
      }
    }
    class WithdrawTransactionsTable extends React.Component {
      render() {
        return (
          <AppContext.Consumer>
            {context => (
              <div>
                <label>{context.jsonTransactions}</label>
              </div>
            )}
          </AppContext.Consumer>
        );
      }
    }
    ReactDOM.render(<App />, document.getElementById("root"));
    
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"></div>
    
    

관련 자료

  • 이전 java - 지속성 단위 오류 - javaxpersistencepersistenceexception : entitymanager에 대한 지속성 제공자가 없습니다
  • 다음 Visual Studio 2017 및 도커