Child ReactJS com 135 linhas de código

Já existem muitos artigos sobre o ReactJS. Mas, para começar a estudar um programador iniciante, você precisa encontrar o início onde estão os fundamentos de sua criação. Eu queria mostrar que não há nada complicado em entender os princípios do desenvolvimento de um front-end nessa estrutura.

JavaScript para bebês

Um método de estudo me permitiu entender a estrutura de muitos sistemas complexos de software e tudo se resume ao fato de que você precisa reescrever o projeto em estudo para obter algum tipo de animal desconhecido que pelo menos se mova um pouco e seja um pouco semelhante ao seu protótipo.

Preciso admitir que sou um back-end e nem sei o que me motivou a escrever um microframework em JavaScript. Mas, francamente, esse é um desejo de aprender JS.

De fato, existe uma boa motivação para criar projetos na forma de módulos / componentes. Na visão dos programadores de back-end, os dados, na melhor das hipóteses, se parecem com objetos JSON, eles devem ser formados na estrutura desejada e enviados onde necessário, e depois fazer o que você quiser com eles. No front-end, na versão mais primitiva, é necessário selecionar os elementos HTML necessários por ID e atualizar seus atributos, além de alterar os nós de texto. Facilite a vida das estruturas JavaScript.

Uma vez eu escrevi meu PHP-Slim-framework, que está longe de ser o original, mas isso realmente me ajuda em projetos PHP. Hoje quero falar sobre como apresentei as origens do desenvolvimento do ReactJS. Eu escrevi um arquivo em 135 linhas de código chamado bots.js e, se você conectá-lo e escrever um componente como no React, poderá até ver algo no navegador. Eu o chamei de ReactKids.

A idéia é dividir o projeto em componentes, adicionar componentes usando javascript e garantir que não haja dependências entre os componentes.

Estrutura padrão HTML:

<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>HelloReactKids</title> <link href="style.css" rel="stylesheet"> </head> <body> <div id="root"></div> <script src="js/bots.js"></script> <script src="js/pict.js"></script> <script src="js/navbar.js"></script> <script src="js/label.js"></script> <script src="js/button.js"></script> <script src="js/app.js"></script> </body> </html> 

Para o aplicativo, especifique id = root e conecte bots.js, conecte os componentes (ou escreva você mesmo) e execute-o em app.js.

O componente no ReactKids é assim:

 function Button(attr) { // attribute components default values if(!attr.labelButton) attr.labelButton = "Click Me" return elem( "button", { padding: "0.65rem", marginTop: "0.4rem", color: "gray", border: "1px solid gray", borderRadius: "0.5rem", background: "#fff", fontSize: "large", cursor: "pointer", }, { id: "btn1", click: btn1Click, }, attr.labelButton ) } function btn1Click(e) { console.log("Clicked!") setAttr(Label({labelContent: "iii!!!"}), 0.6) } 

O componente em nosso caso pode ser apenas uma função na qual params é chamado attr.
Aqui você deve prestar atenção ao motivo pelo qual esse atributo pode ser útil. Bem, antes de tudo, aqueles que estão familiarizados com a reação sabem que é possível "baixar" os dados para os componentes da filha. Ou seja, um componente retorna um componente que retorna um componente e assim por diante até um componente que não tem filhos. No entanto, eles também são usados ​​como pacotes para dados provenientes do servidor. As solicitações para o back-end são, na maioria das vezes, enviadas a partir de funções que manipulam eventos relacionados à interação com a interface do usuário.

Quando o servidor envia JSON (geralmente em texto), ele precisa ser transformado em um objeto JS e feito em algum lugar. É para isso que servem os parâmetros no React e attr na implementação filho.
No attr, você pode compactar todo o objeto JSON recebido do servidor ou pode obter apenas os melhores dados necessários e, possivelmente, complementado com outros dados necessários.

A seguir, seguimos a lógica do React adulto - no início da função, processamos o objeto attr e realizamos outros negócios. Então você precisa retornar o resultado da chamada da função elem (), cuja implementação está em bots.js. Os seguintes parâmetros são transferidos para os parâmetros de chamada:

  1. O nome da tag.
  2. Objeto com estilos (no formato JS)
  3. Atributos para a tag.
  4. Texto, outra tag ou componente (filho) ou nada é passado.

Dê uma olhada no app.js:

 var attr = { labelContent: "Hello React Kids", labelButton: "This button", } rend(document.getElementById("root"), App(attr)) function App(attr) { return elem( "div", { fontFamily: "segoe ui", color: "gray", textAlign: "center", }, { id: "app", }, [ Navbar(attr), Pict(attr), Label(attr), Button(attr), ] ) } 

Nada incomum aqui também. Aqui está o mesmo mais complicado:

 function App(attr) { var cpic1 = CirclePict({id: "img1", src: "./img/img1.jpg", height: "200px"}) var cpic2 = CirclePict({id: "img1", src: "./img/img2.jpg", height: "200px"}) var cpic3 = CirclePict({id: "img1", src: "./img/img3.jpg", height: "200px"}) var txt1 = "   .          ."; var txt2 = "   ,          ."; return elem( "div", { fontFamily: "segoe ui", color: "gray", }, { id: "app", }, [ Pict({id: "logo", src: "./img/logo.png", height: "90%"}), Text({id: "info", text: "you number", direction: "right"}), Label(attr), Outer({id: "outer1", content: [cpic1, cpic2, cpic3]}), Text({id: "txt1", text: txt1, width: "450px"}), Button(attr), Label({id: "lbl2", labelContent: "   "}), Text({id: "txt2", text: txt2, width: "650px", direction: "center"}), RoundPict({id: "well", src: "./img/well.jpg", height: "280px", width: "550"}) ] ) } 

Como você pode ver, incorporamos o componente CirclePict no componente Exterior 3.

As crianças, é claro, notaram a falta de JSX. De fato, foi inventado por programadores preguiçosos e simplesmente facilita o que escrevemos. Como resultado, as tags JSX ainda se transformam em JavaScript.

Agora você precisa ver como isso agora é implementado no bots.js. A estrutura consiste em 3 funções inteiras, de fato elem () e setAttr (), a primeira a criar, a segunda para atualizar o estado do componente e rend () para exibir em app.js.

 function elem(elt, style, attr, item) { /*element */ if(elt) { //  ,      var el = document.createElement(elt); } else { console.log("elt fail") return } /* style */ if(style) { if(typeof(style) == "object") { for(var itm in style) { el.style[itm] = style[itm] } } else { console.log("style is not object type") } } else { console.log("style fail") } /* attr */ if(attr) { if(typeof(attr) == "object") { for(var itm in attr) { if(typeof(attr[itm]) == "function") { el.addEventListener(itm, attr[itm]) } else { // standart el[itm] = attr[itm] } } } else { console.log("attr is not object type") } } else { console.log("attr fail (add ID for element)") } /* item */ if(item) { if(typeof(item) == "string") { var text = document.createTextNode(item) el.appendChild(text) } else if(typeof(item) == "object") { if(Array.isArray(item)) { if(item.length < 1) { console.log("not items in array") return } item.map(function(itm) { el.appendChild(itm) }) } else { el.appendChild(item) } } else { console.log("text is not string or object type") } } else { console.log("text fail") } return el } 

A função processa os parâmetros passados ​​para ele na mesma sequência:

  1. Crie um componente na árvore de documentos.
  2. Adicionando estilos a ele.
  3. Atributos
  4. Adicionando um elemento filho como um texto ou outro elemento.

Ao processar atributos, também verificamos seu tipo, se uma função é recebida como um valor, assume-se que este é um evento e penduramos um grampo nele. Portanto, resta apenas declarar e implementar a função indicada como um evento.

É nessa função de manipulação de eventos que chamamos setAttr (), passando o próprio objeto com o atributo atualizado para ele. Há uma coisa, mas - para cada elemento a ser criado no attr, você deve especificar o ID; caso contrário, ele não será atualizado via setAttr. Ela por identificação encontra-o no DOM.

Quanto ao setAttr (), tudo é pior do que no React, embora para entender os princípios seja suficiente (bom ou quase o suficiente).

 function setAttr(update, slow) { if(slow) { var replace = document.getElementById(update.id) var opamax = 0.99 var opaint = 0.01 var outslow = setInterval(function() { opamax = opamax - opaint if(opamax <= 0) { clearInterval(outslow) update.style.opacity = opamax replace.parentNode.replaceChild(update, replace) var inslow = setInterval(function() { opamax = opamax + opaint update.style.opacity = opamax if(opamax >= 1) { clearInterval(inslow) } }, slow) } replace.style.opacity = opamax }, slow) } else { var replace = document.getElementById(update.id) replace.parentNode.replaceChild(update, replace) } } 

Como você pode ver aqui, apenas manipulações com a árvore de documentos e outro efeito de desbotamento, para que pelo menos pareça e o código pareça uma função, não um mundo hellow.

A coisa mais legal na estrutura de nossas crianças é a função de renderização:

 function rend(root, elem) { root.appendChild(elem) } 

Percebi que é difícil para programadores iniciantes começarem a aprender coisas como React puramente psicologicamente. Tendo visto centenas de megabytes de bibliotecas e milhões de linhas de código, você precisa ficar deprimido e procurar outra coisa. Em particular, eles estão mudando para o Vue. Obviamente, essa também é uma boa estrutura, mas é ainda melhor entender as duas abordagens do desenvolvimento de front-end.

Acontece que ambientes de software complexos surgem de soluções pequenas, mas eficazes. Portanto, desejo boa sorte a todos que buscam o conhecimento do React. Que a força venha conosco!

Source: https://habr.com/ru/post/pt486122/


All Articles